I wrote a little dialog which only contains a TableWigdet. How can I determine the horizontal size of the table ? I want to resize the dialog window so that the table is displayed without a horizontal scrollbar.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
As far as I know, there's no easy way to do it. You have to sum over the widths of the table's columns and then add space for the headers. You also have to add space for the vertical scrollbar and the widget frame. Here is one way to do it,
class myTableWidget(QtGui.QTableWidget):
def sizeHint(self):
width = 0
for i in range(self.columnCount()):
width += self.columnWidth(i)
width += self.verticalHeader().sizeHint().width()
width += self.verticalScrollBar().sizeHint().width()
width += self.frameWidth()*2
return QtCore.QSize(width,self.height())
回答2:
You could use something like that (commented enough I hope):
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyTableWidget(QTableWidget):
def __init__(self, x, y, parent = None):
super(MyTableWidget, self).__init__(x, y, parent)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
# To force the width to use sizeHint().width()
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
# To readjust the size automatically...
# ... when columns are added or resized
self.horizontalHeader().geometriesChanged \
.connect(self.updateGeometryAsync)
self.horizontalHeader().sectionResized \
.connect(self.updateGeometryAsync)
# ... when a row header label changes and makes the
# width of the vertical header change too
self.model().headerDataChanged.connect(self.updateGeometryAsync)
def updateGeometryAsync(self):
QTimer.singleShot(0, self.updateGeometry)
def sizeHint(self):
height = QTableWidget.sizeHint(self).height()
# length() includes the width of all its sections
width = self.horizontalHeader().length()
# you add the actual size of the vertical header and scrollbar
# (not the sizeHint which would only be the preferred size)
width += self.verticalHeader().width()
width += self.verticalScrollBar().width()
# and the margins which include the frameWidth and the extra
# margins that would be set via a stylesheet or something else
margins = self.contentsMargins()
width += margins.left() + margins.right()
return QSize(width, height)
When a row header changes, the width of the whole vertical header changes, but not right away after the signal headerDataChanged
is emitted.
That's why I used a QTimer
to call the updateGeometry
(which must be called when sizeHint
changes) after QTableWidget
has actually updated the vertical header width.