【问题标题】:QLabel word wrap modeQLabel 自动换行模式
【发布时间】:2025-12-13 08:50:02
【问题描述】:

我的标签有时包含没有空格的长文本(计算机中的路径)。

所以 word-wrap 把它包装得很奇怪。

有没有办法让标签的自动换行在单词中间或不仅仅在空格处中断?

【问题讨论】:

    标签: qt label word-wrap


    【解决方案1】:

    一种方法是使用带有QTextDocumentQTextOption 类而不是QLabel。这让您可以使用QTextOption::WrapModeQTextOption::WrapAtWordBoundaryOrAnywhere 应该做你想做的。

    【讨论】:

    • 这是不可接受的,因为 QTextEdit/QTextBrowser 不适合内容。
    • 适合内容?我在问题中没有看到这样的请求。
    • 你是对的,但这是 QLabel 的默认行为,而不是 QTextEdit。此外,让 QTextEdit 具有这种行为并不容易。
    • 因此,答案似乎满足了要求,我猜这完全可以接受。如果您有更好的解决方案,请自己回答。它可能对未来的观众有用。
    【解决方案2】:

    这并不优雅,但确实有效......
    所以说头类有私有:

    QLabel *thisLabel;
    QString *pathName;
    QString *pathNameClean;
    

    当然还有在某个地方定义这个标签。 所以要是这么简单就好了....

    thisLabel->setWordWrap(true);
    

    当且仅当单词有断点时才可以 (应该避免哪些路径)

    如果您以后需要将实际路径用于 QFile,请将其保存在单独的字符串中。 然后手动为每个行号定义一个字符,并将空格插入到字符串中...... 所以我们会说 50 个字符是一个很好的宽度...

        pathNameClean = new QString(pathName);
    
        int c = pathName->length();
    
        if( c > 50)
        {
            for(int i = 1; i <= c/50; i++)
            {
                int n = i * 50;
                pathName->insert(n, " ");
            }
        }
        thisLabel->setText(pathName);
    

    Shazam.... 没有原始空格的模拟 WordWrap...

    请记住 pathName 字符串现在仅用于漂亮的 QLabel 目的,而 pathNameClean 字符串是实际路径。如果您尝试使用空间注入路径打开文件,Qt 程序将崩溃.....

    (如果没有简单的类方法,可能只需要几行代码...... 以及为什么解决问题是程序员最好的工具!)

    【讨论】:

    • 最好使用 Unicode 字符 ZWSP (U+200A) - 零宽度空白。如果您使用该字符,则文本将在您插入的位置换行,但在适合时仍会显示为不带空格。
    • 或者如果您使用Soft Hyphen (U+00AD) 代替,那么在实际换行的地方会有连字符,同样对文本的非换行部分没有视觉效果。
    • 这仅适用于monospaced fonts
    【解决方案3】:

    2020年,PySide2,只是:

     tmp = QLabel()
     tmp.setWordWrap(True)    
    

    【讨论】:

    • 它不能解决文本中没有空格的情况,请阅读问题:“有没有办法让标签的自动换行在单词中间中断或不仅在空白处?”
    • 你可能是对的。我不记得了,我用了一段时间qt。您可以在任何情况下提供正确的解决方案,因为您阅读得更好。祝你好运。
    【解决方案4】:

    QLabel 与其他环绕模式

    我恰好在 2021 年也遇到了同样的问题,所以在这里我将与您分享我迄今为止找到的一些最佳答案。

    TextWrapAnywhere QLabel

    子类QLabel 并实现paintEvent,当您drawItemText 时,您可以将文本对齐方式设置为TextWrapAnywhere

    from PyQt5.QtCore import Qt
    from PyQt5.QtGui import QPainter
    from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QStyleOption, QVBoxLayout, QWidget, QStyle
    
    class SuperQLabel(QLabel):
        def __init__(self, *args, **kwargs):
            super(SuperQLabel, self).__init__(*args, **kwargs)
    
            self.textalignment = Qt.AlignLeft | Qt.TextWrapAnywhere
            self.isTextLabel = True
            self.align = None
    
        def paintEvent(self, event):
    
            opt = QStyleOption()
            opt.initFrom(self)
            painter = QPainter(self)
    
            self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self)
    
            self.style().drawItemText(painter, self.rect(),
                                      self.textalignment, self.palette(), True, self.text())
    
    
    class MainWindow(QMainWindow):
        def __init__(self, *args, **kwargs):
            super(MainWindow, self).__init__(*args, **kwargs)
    
            self.setFixedSize(100, 200)
    
            self.label = QLabel()
            self.label.setWordWrap(True)
            self.label.setText("1111111111111111111111111111")
    
            self.slabel = SuperQLabel()
            self.slabel.setText("111111111111111111111111111")
    
            self.centralwidget = QWidget()
            self.setCentralWidget(self.centralwidget)
    
            self.mainlayout = QVBoxLayout()
            self.mainlayout.addWidget(self.label)
            self.mainlayout.addWidget(self.slabel)
    
            self.centralwidget.setLayout(self.mainlayout)
    
    
    if __name__ == "__main__":
        import sys
        app = QApplication(sys.argv)
        w = MainWindow()
        w.show()
        sys.exit(app.exec_())
    

    在字符而不是空格处换行

    根据@ekhumoro 提供的this answer(在操作的评论中),如果您正在寻找基于逗号换行的方法,您可以在要换行的字符后插入一个零宽度空格并使用内置的在自动换行功能中。

    这是一个例子:

    from PyQt5.QtCore import QRect, Qt
    from PyQt5.QtGui import QPainter
    from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QStyleOption, QStylePainter, QVBoxLayout, QWidget, QStyle
    
    
    class CommaWrapableQLabel(QLabel):
        def __init__(self, *args, **kwargs):
            super(CommaWrapableQLabel, self).__init__(*args, **kwargs)
    
        def setWordWrapAtAnychar(self, char):
            newtext = self.text().replace(char, f"{char}\u200b")
            self.setText(newtext)
            self.setWordWrap(True)
    
    
    class MainWindow(QMainWindow):
        def __init__(self, *args, **kwargs):
            super(MainWindow, self).__init__(*args, **kwargs)
    
            self.setFixedSize(100, 200)
    
            self.label = QLabel()
            self.label.setWordWrap(True)
            self.label.setText(
                'Dog,Rabbit,Train,Car,Plane,Cheese,Meat,Door,Window')
    
            self.slabel = CommaWrapableQLabel()
            self.slabel.setText(
                'Dog,Rabbit,Train,Car,Plane,Cheese,Meat,Door,Window')
            self.slabel.setWordWrapAtAnychar(",")
    
            self.centralwidget = QWidget()
            self.setCentralWidget(self.centralwidget)
    
            self.mainlayout = QVBoxLayout()
            self.mainlayout.addWidget(self.label)
            self.mainlayout.addWidget(self.slabel)
    
            self.centralwidget.setLayout(self.mainlayout)
    
    
    if __name__ == "__main__":
        import sys
        app = QApplication(sys.argv)
        w = MainWindow()
        w.show()
        sys.exit(app.exec_())
    

    【讨论】: