开发者

QListWidget adjust size to content

Is it possible to adjust QListWidget height and widt开发者_StackOverflowh to it's content?

sizeHint() always returns 256, 192 no matter what its content is.

QListWidgetItem's sizeHint() returns -1, -1, so I can not get content width.

Problem the same as here - http://www.qtcentre.org/threads/31787-QListWidget-width , but there is no solution.

QListWidget adjust size to content

import sys
from PyQt4.QtGui import *

class MainWindow(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        list = QListWidget()
        list.addItem('111111111111111')

        vbox = QVBoxLayout(self)
        vbox.addWidget(list)

app = QApplication(sys.argv)
myapp = MainWindow()
myapp.show()
sys.exit(app.exec_())


sizeHint() always returns 256, 192 no matter what its content is.

Thats because this is the size of the QListWidget, the viewport, not the items. sizeHintForColumn() will give you the max size over all items, so you can resize the widget like this:

list.setMinimumWidth(list.sizeHintForColumn(0))

If you don't want to force minimum width, then subclass and provide this as the size hint instead. E.g.:

class ListWidget(QListWidget):
  def sizeHint(self):
    s = QSize()
    s.setHeight(super(ListWidget,self).sizeHint().height())
    s.setWidth(self.sizeHintForColumn(0))
    return s


Using takois answer I played around with the sizeHintForColumn or sizeHintForRow and found that you have to add slightly larger numbers, because there might be some style dependent margins still. ekhumoros comment then put me on the right track.

In short the full size of the list widget is:

list.sizeHintForColumn(0) + 2 * list.frameWidth()
list.sizeHintForRow(0) * list.count() + 2 * list.frameWidth())

According to the comment by Violet it may not work in Qt 5.

Also be aware that setting the size to the content, you don't need scrollbars, so I turn them off.

My full example for a QListWidget ajusted to its content size:

from PySide import QtGui, QtCore

app = QtGui.QApplication([])

window = QtGui.QWidget()
layout = QtGui.QVBoxLayout(window)
list = QtGui.QListWidget()
list.addItems(['Winnie Puh', 'Monday', 'Tuesday', 'Minnesota', 'Dracula Calista Flockhart Meningitis', 'Once', '123345', 'Fin'])
list.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
list.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
list.setFixedSize(list.sizeHintForColumn(0) + 2 * list.frameWidth(), list.sizeHintForRow(0) * list.count() + 2 * list.frameWidth())
layout.addWidget(list)

window.show()

app.exec_()


In order to effectively use sizeHint, you have to override it, at least in c++. In my experience, the default implementations for widgets can be pretty useless when you want a specific behavior. Attempts to force what you want with spacers or layouts end in disaster. If you can derive from QListWidget and override sizeHint, you can iterate through your items and find the longest string, then do some kind of magic to determine how wide it should be.

That's what I'd do, anyway.


First you should get your largest string in the list, that is easy to obtain.

After you get that string, do the following:

QFontMetrics * fm = new QFontMetrics(widget->font());
QRect rect;
rect = fm->boundingRect(string);

rect.width() has the width in pixels of the largest string rect.height() has it's height.

Set the QListWidget width to that rect's width (plus the margins) and it's height to that rect's height times the number of items

I didn't test the code, but hope it puts you on the right track


QListWidget *valList;

valList =  new QListWidget(this);

valList->setSizePolicy (QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored));
valList->setMinimumSize (QSize(1111, 111));


You need to get the QHeaderView of your QListWidget and adjust its resize mode.

Read this documentation for more information

http://doc.qt.nokia.com/latest/qheaderview.html#ResizeMode-enum

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜