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

问题描述 投票:0回答:3

我需要使用 QLabel 显示文本,并满足以下要求:

  1. 自动换行
  2. 标签单行时根据文字长度从小宽度扩展到全宽度
  3. 标签占用多行时始终为全宽
  4. 标签的背景填充了一些颜色

我尝试将带有 sizePolicy(首选,首选)的 QLabel 和带有 sizePolicy(扩展,最小值)的 QSpacerItem 放入 QHBoxLayout 中。

layout

我希望文本在到达右侧之前被换行。

expect

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

result

如何防止这种不必要的自动换行?

复制代码

注意

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

enter image description here enter image description here

相关问题

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

qt qt4 qlabel
3个回答
2
投票
  1. 这可以通过仅在需要时设置标签的
    wordWrap
    来解决。要触发标签尺寸更改,您可以通过从
    QLabel
    补充来制作自定义标签。下面是一个例子。

当文本添加到标签时。最初设置自动换行为 false,它将扩展直至达到帧大小。如果超过了帧大小,则自动换行设置为 true。

  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. 主窗口.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. 主窗口.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布局:框架内的水平布局。

    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 的子类。

之前

之后

抱歉我的英语不好。


0
投票

我也很困惑这是如何运作的。我花了几天时间才得到结果。现在,消息可以根据文本正确缩放。当窗口大小调整时它也起作用。将 MessageWidget 类添加到scrollArea。

import sys
from PyQt6 import QtCore, QtGui
from PyQt6.QtWidgets import QApplication, QTextEdit, QWidget, QVBoxLayout, QMainWindow, QTabWidget, QGridLayout
from PyQt6.uic import loadUi
import qt_ui.ai_dating_resources

class MessageWidget(QWidget):    
    def __init__(self, in_text: str):
        super(MessageWidget, self).__init__()
        loadUi("qt_ui/single_message.ui", self)
        self.textEdit_companion_message.setText(in_text)
        
    def minimumSizeHint(self):
        frame_width = self.width() - self.label_companion_ava.width() - self.label_companion_time.width() - 80
        text_width = self.get_width_from_text() + 32
        cur_width = text_width if text_width < frame_width else frame_width
        self.textEdit_companion_message.setFixedWidth(cur_width)
        self.label_companion_time.move(self.label_companion_ava.width() + cur_width + 4, 0)

        cur_clone = self.textEdit_companion_message.document().clone()
        cur_clone.setTextWidth(cur_width)
        cur_height = int(cur_clone.size().height() + self.textEdit_companion_message.frameWidth() * 2) + 2

        self.textEdit_companion_message.setFixedHeight(cur_height)
        return QtCore.QSize(0, cur_height)
    
    def sizeHint(self):
        return self.minimumSizeHint()
    
    def resizeEvent(self, event):
        super().resizeEvent(event)
        self.updateGeometry()
        
    def get_width_from_text(self) -> int:
        cur_fm = QtGui.QFontMetrics(self.textEdit_companion_message.font())
        return cur_fm.horizontalAdvance(self.textEdit_companion_message.toPlainText())

滚动区域 调整大小

© www.soinside.com 2019 - 2024. All rights reserved.