0

You'd think that word wrapping on a QLabel should be simple, just apply setWordWrap(True) to the label and PyQt will figure out the rest. However, in my program, that doesn't happen. The wrap occurs significantly earlier than the end of the widget, while also not having a decent enough height to actually show the full text. I've attached a minimally reproducible example to show what I mean. If you comment out the line self.content.setWordWrap(True), you can see that everything works as expected (with the long text running off the window, requiring a scrollbar.

from PyQt5.QtGui import *
from PyQt5.QtCore import *


class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        ## Set up Window layout
        super(MainWindow, self).__init__(*args, **kwargs)

        self.setLayout(QGridLayout())
        self.setGeometry(300, 50, 1500, 700)
        self.layout().setColumnStretch(0, 1)
        self.layout().setColumnStretch(1, 2)

        leftGroup = QGroupBox('Left Group')
        self.layout().addWidget(leftGroup, 0, 0)

        rightGroup = QGroupBox('Right Group')
        self.layout().addWidget(rightGroup, 0, 1)

        rightLayout = QVBoxLayout(rightGroup)
        rightLayout.addWidget(EventsWidget(False, {'first': {'Date': '762', 'Content': 'Documented in the Fulda foundation book'},
                                                  'second': {'Date': '10/28/1485', 'Content': 'Here is a super long message to test how the display works when this has a lot of content.'
                                                                                              'Let us hope the widget handles the long text well or else it will be difficult to do the'
                                                                                              'reformatting manually. I have faith since this is not a normal QLineEdit, but a QPlainTextEdit'}}))

class EventsWidget(QGroupBox):
    def __init__(self, edit, event_list):
        super().__init__('Events')

        self.setLayout(QVBoxLayout())

        self.event_list = event_list  # The dict of events, key: uuid, data: date, content

        scrollWidget = QWidget()
        scrollWidget.layout = QVBoxLayout()
        scrollWidget.setLayout(scrollWidget.layout)

        for e in self.event_list:
            event_data = self.event_list[e]
            scrollWidget.layout.addWidget(EventWidget(edit, event_data['Date'], event_data['Content']))

        scrollWidget.layout.addStretch(1)

        ## Create scrolling mechanics
        scroll = QScrollArea()

        scroll.setWidget(scrollWidget)
        scroll.setWidgetResizable(True)

        self.layout().addWidget(scroll)

class EventWidget(QWidget):
    def __init__(self, edit, date, content):
        super().__init__()

        self.setLayout(QGridLayout())
        margin = 0
        self.layout().setContentsMargins(margin, margin, margin, margin)

        if edit:
            self.date = QLineEdit(date)
            self.content = QPlainTextEdit(content)

        else:
            self.date = QLabel(date)
            self.date.setFixedWidth(75)
            self.content = QLabel(content)
            self.content.setWordWrap(True)

        self.layout().addWidget(self.date, 0, 0, alignment=Qt.AlignHCenter)
        self.layout().addWidget(self.content, 0, 1, alignment=Qt.AlignLeft)
        self.layout().setColumnStretch(1, 1)


if __name__ == '__main__':
    ## Creates a QT Application
    app = QApplication([])

    ## Creates a window
    window = MainWindow()

    ## Shows the window
    window.show()
    app.exec_()

I appreciate any and all suggestions for what I'm doing wrong.

Here's an image of what the label looks like with word wrapping on:

image

musicamante
  • 41,230
  • 6
  • 33
  • 58
kairom13
  • 7
  • 4
  • Remove the `alignment` argument in `addWidget()`. As explained in the [documentation](https://doc.qt.io/qt-5/qgridlayout.html#addWidget-1), "The default alignment is 0, which means that the widget fills the entire cell.": if you specify the alignment, the widget will only occupy the size of its *size hint*, and QLabel only provides an arbitrary size hint for word wrapped text. – musicamante Aug 26 '22 at 18:06
  • @musicamante Ahh ok. Thanks. Can you add that as an answer so I can accept it? Also, is there a reason why the alignment argument does that? If I wanted a different alignment for the label, how would I set that? – kairom13 Aug 26 '22 at 18:12
  • Note that I updated my first comment, explaining why that happens; also read the answers for which this has been marked as duplicate. If you want to set the *text* alignment of the label, then set the alignment *for* the label, using [`QLabel.setAlignment()`](https://doc.qt.io/qt-5/qlabel.html#alignment-prop). Text alignment and layout alignment are two very different things. – musicamante Aug 26 '22 at 18:23

0 Answers0