如何防止QLabel不必要的word-wrapping?
How to prevent QLabel from unnecessary word-wrapping?
我需要使用具有以下要求的 QLabel 显示文本:
- 自动换行
- 根据文本长度从小宽扩展到全宽,而label占单行
- 当标签占用多行时总是全宽
- 标签的背景填充了一些颜色
我尝试将带有 sizePolicy (Preferred, Preferred) 的 QLabel 和带有 sizePolicy (Expanding, Minimum) 的 QSpacerItem 放入 QHBoxLayout 中。
我希望文本在到达右侧之前不会换行。
但是我发现文本在到达右侧之前被换行了。
如何避免这种不必要的word-wrapping?
复制码
备注
- 如果我不在HBox中放置spacer,则满足要求1和3,但满足2(不存在文本的区域用背景色填充。此时,我不希望出现这种行为)。
- 如果我禁用 word-wrapping,则满足要求 2,但 1.
相关问题
- Why does QLabel prematurely wrap?
这个问题是关于类似的问题,但是没有布局。
- 这个可以通过只在需要时设置标签的
wordWrap
来解决。要触发标签的大小更改,您可以通过从 QLabel
补充来制作自定义标签。下面是一个例子。
当文本被添加到标签时。最初使用自动换行 false,它会扩展直到达到帧大小。如果它超过帧大小,则自动换行设置为 true。
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
mylabel.cpp
#include "mylabel.h"
MyLabel::MyLabel():QLabel()
{
}
MyLabel::~MyLabel()
{
}
void MyLabel::resizeEvent(QResizeEvent *)
{
emit labelSizeChange();
}
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
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);
}
GUI 布局:框架内的水平布局。
我在制作聊天应用时遇到了同样的问题。受 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
抱歉我的英语不好。
我需要使用具有以下要求的 QLabel 显示文本:
- 自动换行
- 根据文本长度从小宽扩展到全宽,而label占单行
- 当标签占用多行时总是全宽
- 标签的背景填充了一些颜色
我尝试将带有 sizePolicy (Preferred, Preferred) 的 QLabel 和带有 sizePolicy (Expanding, Minimum) 的 QSpacerItem 放入 QHBoxLayout 中。
我希望文本在到达右侧之前不会换行。
但是我发现文本在到达右侧之前被换行了。
如何避免这种不必要的word-wrapping?
复制码
备注
- 如果我不在HBox中放置spacer,则满足要求1和3,但满足2(不存在文本的区域用背景色填充。此时,我不希望出现这种行为)。
- 如果我禁用 word-wrapping,则满足要求 2,但 1.
相关问题
- Why does QLabel prematurely wrap?
这个问题是关于类似的问题,但是没有布局。
- 这个可以通过只在需要时设置标签的
wordWrap
来解决。要触发标签的大小更改,您可以通过从QLabel
补充来制作自定义标签。下面是一个例子。
当文本被添加到标签时。最初使用自动换行 false,它会扩展直到达到帧大小。如果它超过帧大小,则自动换行设置为 true。
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
mylabel.cpp
#include "mylabel.h" MyLabel::MyLabel():QLabel() { } MyLabel::~MyLabel() { } void MyLabel::resizeEvent(QResizeEvent *) { emit labelSizeChange(); }
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
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); }
GUI 布局:框架内的水平布局。
我在制作聊天应用时遇到了同样的问题。受 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
抱歉我的英语不好。