【问题标题】:Set optimal size of a dialog window containing a TableWidget设置包含 TableWidget 的对话框窗口的最佳大小
【发布时间】:2011-08-28 02:38:07
【问题描述】:

我写了一个只包含一个 TableWigdet 的小对话框。如何确定表格的水平尺寸?我想调整对话窗口的大小,使表格显示时没有水平滚动条。

【问题讨论】:

    标签: pyqt pyqt4


    【解决方案1】:

    据我所知,没有简单的方法可以做到这一点。您必须对表格列的宽度求和,然后为标题添加空间。您还必须为垂直滚动条和小部件框架添加空间。这是一种方法,

    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())
    

    【讨论】:

    • 几年后,这仍然有效。但是,我想知道,是否仍然没有更好的(即内置)方法(在 PySide2 中)?
    【解决方案2】:

    你可以使用类似的东西(我希望评论足够多):

    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 的原因(它在QTableWidget 实际更新垂直标题宽度之后,必须在sizeHint 更改时调用。

    【讨论】:

    • 这对我来说效果很好,而“接受”的答案却没有。一个原因可能是我使用的 QTableView 没有 Terry 先生的解决方案中使用的 columnCount 方法。请注意,对于 QTableView,您需要在构造函数的早期设置模型才能使此解决方案起作用,因为它使用模型来判断标题是否更改。
    • 警告词:我在一个未保存的对话框中使用了MyTableWidget 的这个实现(例如,对话框是用同样的方法创建的并且超出了范围),它给了我一个@ 987654328@ 错误。我认为QTimer 在小部件已经被垃圾收集后试图调用self.updateGeometry(这可能吗?)。无论如何,我只是用对股票 self.updateGeometry 的调用替换了对 self.updateGeometryAsync 的调用,它对我来说仍然很好。
    猜你喜欢
    • 2018-12-18
    • 2013-10-05
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    相关资源
    最近更新 更多