Re: [PyQt] HeightForWidth label

2013-01-10 Thread Mads Ipsen

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

2013-01-09 Thread Hans-Peter Jansen
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

2013-01-09 Thread 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.


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