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.
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
精彩评论