Re: [PyQt] HeightForWidth label
Dear Pete, Thanks a lot for your input. To some extend its too bad that this feature cannot be implemented in a proper fashion - especially when the documentation of Qt tells you that it can. Best regards, Mads On 09/01/2013 22:00, Hans-Peter Jansen wrote: Dear Mads, Am Mittwoch, 9. Januar 2013, 15:56:29 schrieb Mads Ipsen: Hi, 4-5 years I needed a widget with the following properties: * Display text incl. HTML * Text should be wrapped on several lines * When the widget is put into a layout, the height of the widget should be adjusted in such a way that the text exactly fits the widget geometry This subwidget should be used in a layout to provide some detail on how the other GUI elements in the layout work but only consume a minimum space to display its content. I thought this was an easy one - but each time I return to the challenge I always end by giving up. The main problem is that the layout breaks down when heightForWidth() is implemented and a QSizePolicy with setHeightForWidth(True) is used. It can shrink to infinitely small. Apparently this is Qt bug. Yes, been there, done that, and failed in similar ways. The best thing I could come up on this was: use a QTextBrowser for the text: self.aboutText.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.aboutText.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.aboutText.setLineWrapMode(QtGui.QTextEdit.NoWrap) self.aboutText.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) self.aboutText.setHtml("...") w = self.aboutText.document().idealWidth() self.aboutText.document().setTextWidth(w) ds = self.aboutText.document().size() self.aboutText.setMinimumSize(int(ds.width() + 3), int(ds.height() + 3)) self.aboutText.updateGeometry() self.layout().setSizeConstraint(QtGui.QLayout.SetFixedSize) with this, you can even provide clickable links (but disable openLinks prop): @QtCore.pyqtSignature("const QUrl &") def on_aboutText_anchorClicked(self, url): QtGui.QDesktopServices.openUrl(url) Maybe it gets you going.. Cheers, Pete ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt -- +-+ | Mads Ipsen | +--+--+ | Gåsebæksvej 7, 4. tv | | | DK-2500 Valby| phone: +45-29716388 | | Denmark | email: mads.ip...@gmail.com | +--+--+ ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] HeightForWidth label
Dear Mads, Am Mittwoch, 9. Januar 2013, 15:56:29 schrieb Mads Ipsen: > Hi, > > 4-5 years I needed a widget with the following properties: > > * Display text incl. HTML > * Text should be wrapped on several lines > * When the widget is put into a layout, the height of the widget > should be adjusted in such a way that the text exactly fits the > widget geometry > > This subwidget should be used in a layout to provide some detail on how > the other GUI elements in the layout work but only consume a minimum > space to display its content. > > I thought this was an easy one - but each time I return to the challenge > I always end by giving up. > > The main problem is that the layout breaks down when heightForWidth() is > implemented and a QSizePolicy with setHeightForWidth(True) is used. It > can shrink to infinitely small. Apparently this is Qt bug. Yes, been there, done that, and failed in similar ways. The best thing I could come up on this was: use a QTextBrowser for the text: self.aboutText.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.aboutText.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.aboutText.setLineWrapMode(QtGui.QTextEdit.NoWrap) self.aboutText.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) self.aboutText.setHtml("...") w = self.aboutText.document().idealWidth() self.aboutText.document().setTextWidth(w) ds = self.aboutText.document().size() self.aboutText.setMinimumSize(int(ds.width() + 3), int(ds.height() + 3)) self.aboutText.updateGeometry() self.layout().setSizeConstraint(QtGui.QLayout.SetFixedSize) with this, you can even provide clickable links (but disable openLinks prop): @QtCore.pyqtSignature("const QUrl &") def on_aboutText_anchorClicked(self, url): QtGui.QDesktopServices.openUrl(url) Maybe it gets you going.. Cheers, Pete ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] HeightForWidth label
Hi, 4-5 years I needed a widget with the following properties: * Display text incl. HTML * Text should be wrapped on several lines * When the widget is put into a layout, the height of the widget should be adjusted in such a way that the text exactly fits the widget geometry This subwidget should be used in a layout to provide some detail on how the other GUI elements in the layout work but only consume a minimum space to display its content. I thought this was an easy one - but each time I return to the challenge I always end by giving up. The main problem is that the layout breaks down when heightForWidth() is implemented and a QSizePolicy with setHeightForWidth(True) is used. It can shrink to infinitely small. Apparently this is Qt bug. Another approach is to call updateGeometry() when a resizeEvent() occurs and call setFixedHeight(h) using a width dependent height. But this also gives rise to some weird layout behavior. If anybody has any good suggestions on how to approach this, please let me know. I attach a small snippet that reproduces the layout resizing behavior. Best regards, Mads -- +-+ | Mads Ipsen | +--+--+ | Gåsebæksvej 7, 4. tv | | | DK-2500 Valby| phone: +45-29716388 | | Denmark | email:mads.ip...@gmail.com | +--+--+ import sys from PyQt4 import QtCore, QtGui class Square(QtGui.QLabel): def __init__(self, parent=None): QtGui.QLabel.__init__(self, parent) self.setAutoFillBackground(True) palette = QtGui.QPalette() palette.setColor(QtGui.QPalette.Window, QtGui.QColor('red')) self.setPalette(palette) policy = self.sizePolicy() policy.setHeightForWidth(True) self.setSizePolicy(policy) def sizeHint(self): return QtCore.QSize(128, 128) def heightForWidth(self, width): return width class Widget(QtGui.QWidget): def __init__(self, parent=None): # Call base class constructor QtGui.QWidget.__init__(self, parent) # Add a layout layout = QtGui.QVBoxLayout() self.setLayout(layout) # Add Square label = Square() layout.addWidget(label) spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) layout.addItem(spacerItem) # Some dummy button self._push_button = QtGui.QPushButton('Press me') layout.addWidget(self._push_button) if __name__ == "__main__": app = QtGui.QApplication(sys.argv) widget = Widget() widget.show() sys.exit(app.exec_()) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt