Я написал небольшой диалог, который содержит только TableWigdet. Как определить размер стола по горизонтали? Я хочу изменить размер диалогового окна, чтобы таблица отображалась без горизонтальной полосы прокрутки.

6
rocksportrocker 25 Авг 2011 в 15:07

2 ответа

Лучший ответ

Насколько я знаю, простого способа сделать это нет. Вам нужно просуммировать ширину столбцов таблицы, а затем добавить место для заголовков. Вы также должны добавить место для вертикальной полосы прокрутки и рамки виджета. Вот один из способов сделать это,

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())
6
Stephen Terry 25 Авг 2011 в 18:31

Вы можете использовать что-то вроде этого (надеюсь, достаточно прокомментировано):

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)

Когда заголовок строки изменяется, ширина всего вертикального заголовка изменяется, но не сразу после того, как излучается сигнал headerDataChanged.
Вот почему я использовал QTimer для вызова updateGeometry (который должен вызываться при изменении sizeHint) после того, как QTableWidget фактически обновил ширину вертикального заголовка.

6
alexisdm 27 Авг 2011 в 18:38