如何防止QLabel进行不必要的换行?

6
我需要使用QLabel显示文本,并满足以下要求:
  1. 自动换行
  2. 当标签只占一行时,根据文本长度从小宽度扩展到全宽度
  3. 当标签占多行时,始终保持全宽度
  4. 标签的背景填充有颜色
我尝试将具有sizePolicy(Preferred,Preferred)的QLabel和具有sizePolicy(Expanding,Minimum)的QSpacerItem放入QHBoxLayout中。

layout

我希望您能够在文本到达右侧之前不要换行。

expect

但是我发现文本在到达右侧之前就被换行了。

result

如何防止不必要的单词换行?

复制代码

注意事项

  1. 如果我不在HBox中放置间隔符,则满足要求1和3,但不满足要求2(文本不存在的区域填充背景颜色。此时,我不想要这种行为)。
  2. 如果禁用单词换行,则满足要求2,但不满足要求1。

enter image description here enter image description here

相关问题

这个问题与类似的问题有关,但没有布局。


无法访问这些图形。你能在这里添加吗?另外,你是否为QLabel设置了最小和最大宽度? - techneaz
在这个例子中添加间隔是毫无意义的,因为您可以只需删除间隔即可获得所需的行为。您应该描述实际用例。您可以使用 QBoxLayout::setStretch 来确定分配给每个可扩展项的空间量(例如,将 stretch=4 设置为标签,将 spacer 设置为 1 将使标签占据全宽的 4/5)。如果布局中的其他项具有固定大小,则可扩展的标签将占用所有可用空间。 - Pavel Strakhov
@techneaz 感谢您找到了问题。我已经修复了链接。 - tetsurom
@techneaz 我没有设置最小/最大尺寸,或者我使用它们的默认值,但我认为这是可以的。因为我无法给出恒定的值。 - tetsurom
@PavelStrakhov 谢谢。对不起,问题可能不太清楚。我应该用一些颜色填充标签的背景,但是文本不存在的区域不应该被填充。因此,间隔器不是无用的。如果我删除间隔器,标签将占据所有空间。其次,在这种情况下,拉伸不适合我。因为我不想固定标签所给出的空间大小。我想根据文本的长度来给出空间。 - tetsurom
2个回答

2
  1. 只有在需要时才设置标签的wordWrap即可解决此问题。要触发标签大小的更改,您可以通过从QLabel重新实现来创建自定义标签。以下是一个示例。

当文本添加到标签中时,初始状态下不启用换行,它将扩展直到达到帧大小。如果超过了帧大小,则将启用换行。

  1. mylabel.h

    #ifndef MYLABEL_H
    #define MYLABEL_H
    
    #include <QLabel>
    
    class MyLabel : public QLabel
    {
         Q_OBJECT
    public:
       explicit MyLabel();
        ~MyLabel();
    
    signals:
        void labelSizeChange();
    protected slots:
        void resizeEvent(QResizeEvent *);
    
    };
    
    #endif // MYLABEL_H
    
  2. mylabel.cpp

    #include "mylabel.h"
    
    MyLabel::MyLabel():QLabel()
    {
    }
    
    MyLabel::~MyLabel()
    {
    }
    
    void MyLabel::resizeEvent(QResizeEvent *)
    {
        emit labelSizeChange();
    }
    
  3. mainwindow.h

        #ifndef MAINWINDOW_H
        #define MAINWINDOW_H
    
        #include <QMainWindow>
        #include <QtCore>
        #include <mylabel.h>
    
    
        namespace Ui {
        class MainWindow;
        }
    
        class MainWindow : public QMainWindow
        {
            Q_OBJECT
    
        public:
            explicit MainWindow(QWidget *parent = 0);
            ~MainWindow();
    
        private slots:
    
            void lableSettings();
            void on_pbShort_clicked();
            void on_pbMedium_clicked();
            void on_pbLong_clicked();
    
            void addTextToLabel(QString text);
        private:
            Ui::MainWindow *ui;
    
            MyLabel myLabel;
    
            QString lorem;
    
        };
    
         #endif // MAINWINDOW_H
    
  4. mainwindow.cpp

    #include "mainwindow.h"
        #include "ui_mainwindow.h"
    
    
        MainWindow::MainWindow(QWidget *parent) :
            QMainWindow(parent),
            ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
    
            ui->horizontalLayout->addWidget(&myLabel);
            ui->horizontalLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding));
    
            myLabel.setStyleSheet("Background-color:black;color:white");
            myLabel.setWordWrap(false);
            myLabel.setMinimumWidth(0);
            myLabel.setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
    
            connect(&myLabel,SIGNAL(labelSizeChange()),this,SLOT(lableSettings()));
    
            lorem ="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
        }
    
        MainWindow::~MainWindow()
        {
            delete ui;
        }
    
    
        void MainWindow::addTextToLabel(QString text)
        {
            myLabel.setWordWrap(false);
            myLabel.setMinimumWidth(0);
            myLabel.setText(text);
    
        }
    
        void MainWindow::lableSettings()
        {
    
            if(myLabel.width()> ui->frame->width()-20)
            {
                myLabel.setWordWrap(true);
                myLabel.setMinimumWidth(ui->frame->width()-20);
             // Note the value 20 depends on the layout spacing 
             //between the Horizontal layout and the frame. 
             //If this value is less. The whole windo will start resizing.
            }
        }
    
        void MainWindow::on_pbShort_clicked()
        {
             addTextToLabel(lorem.left(15));
        }
    
        void MainWindow::on_pbMedium_clicked()
        {
            addTextToLabel(lorem.left(150));
        }
    
        void MainWindow::on_pbLong_clicked()
        {
            addTextToLabel(lorem);
        }
    
  5. GUI layout : HorizontalLayout inside a frame.

    enter image description here


1

在制作聊天应用程序时,我遇到了同样的问题。受到techneaz的答案的启发,我发现使用QFontMetrics是一种更清洁的计算文本宽度的方式。

因此,如果计算出的文本宽度加上一些填充小于所需的最大宽度,则将标签的固定宽度设置为“计算出的文本宽度加上一些填充”,否则将其设置为所需的最大宽度。

以下是我的pyqt代码:

class TextBubbleView(BubbleView):

    PADDING = 18
    MAX_WIDTH = 400

    def __init__(self, msg: Message):
        super().__init__(msg)
        self.setWordWrap(True)
        fm = QFontMetrics(self.font())
        width = fm.width(msg.content) + TextBubbleView.PADDING
        if width < TextBubbleView.MAX_WIDTH:
            self.setFixedWidth(width)
        else:
            self.setFixedWidth(TextBubbleView.MAX_WIDTH)
        self.setText(msg.content)

BubbleView是QLabel的子类。

before

after

抱歉我的英语不好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接