【问题标题】:How strech QTableWidget last column in any cases在任何情况下如何拉伸 QTableWidget 的最后一列
【发布时间】:2021-07-05 06:46:46
【问题描述】:

如何使最后一列始终延伸到剩余空间?

这是我不想看到的

这是我正在使用的代码:

import sys
from PyQt5.QtWidgets import *

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(300, 300)
        self.show()

        self.tableWidget = QTableWidget()
        self.setCentralWidget(self.tableWidget)

        self.tableWidget.setColumnCount(2)
        self.tableWidget.setHorizontalHeaderLabels(["column 1", "column 2"])
        self.tableWidget.setStyleSheet("QHeaderView::section{Background-color:cyan;}")
        self.tableWidget.setSortingEnabled(True)

        nb = 25
        self.tableWidget.setRowCount(nb)
        for i in range(nb):
            self.tableWidget.setItem(i, 0, QTableWidgetItem("A"*(nb-i)))
            self.tableWidget.setItem(i, 1, QTableWidgetItem("B"*(nb-i)))
        
        self.tableWidget.resizeColumnsToContents()
        self.tableWidget.horizontalHeader().setStretchLastSection(True)

app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())

以及如何重现这种不需要的行为:启动 prog,向右滚动水平滚动条,然后水平调整窗口的宽度

【问题讨论】:

    标签: pyqt5 qtablewidget qtablewidgetitem


    【解决方案1】:

    这似乎是updateGeometries 代码中的一个小错误,当可见列保持不变且滚动模式为ScrollPerItem 时,它不会更新标题偏移量;垂直标题也会发生这种情况,但通常不太明显,因为行通常较小。
    请注意,即使没有将列(或行)的大小调整为内容,该问题也存在,只要至少有两个部分可见并且不适合视图,就会出现问题,从而导致显示滚动条。

    一种可能的解决方案是对表进行子类化,覆盖resizeEvent() 并在需要时调用setOffsetToLastSection()。从理论上讲,它应该在 updateGeometries 调用中完成,但考虑到这只发生在调整大小时(并且经常调用 updateGeometries),我怀疑这是否有意义。
    做更多的实验和研究以确保对滚动模式和滚动条的检查足够,最终submit a bug 可能是个好主意。

    class MyTable(QtWidgets.QTableWidget):
        def resizeEvent(self, event):
            checkHorizontal = (self.horizontalScrollMode() == self.ScrollPerItem and 
                self.horizontalScrollBar().maximum() >= 1 and 
                self.horizontalScrollBar().value() == self.horizontalScrollBar().maximum())
            checkVertical = (self.verticalScrollMode() == self.ScrollPerItem and 
                self.verticalScrollBar().maximum() >= 1 and 
                self.verticalScrollBar().value() == self.verticalScrollBar().maximum())
            super().resizeEvent(event)
            if checkHorizontal:
                self.horizontalHeader().setOffsetToLastSection()
            if checkVertical:
                self.verticalHeader().setOffsetToLastSection()
    

    如果您打算使用大量表和子类,并且希望始终使用这种行为,您可以通过直接修补 QTableView 类(因为它是 QTableWidget 继承的)来做一个小“修改”;请注意,这个必须在类的模块被导入后立即完成(所以,在你的 main 脚本的最开始,在第一次导入 QtWidgets 之后时间):

    # create a new reference for the default implementation
    QTableView._resizeEvent = QTableView.resizeEvent
    # the general fix
    def resizeEventFix(self, event):
        checkHorizontal = (self.horizontalScrollMode() == self.ScrollPerItem and 
            self.horizontalScrollBar().maximum() >= 1 and 
            self.horizontalScrollBar().value() == self.horizontalScrollBar().maximum())
        checkVertical = (self.verticalScrollMode() == self.ScrollPerItem and 
            self.verticalScrollBar().maximum() >= 1 and 
            self.verticalScrollBar().value() == self.verticalScrollBar().maximum())
        # call the original implementation we renamed before
        QTableView._resizeEvent(self, event)
        if checkHorizontal:
            self.horizontalHeader().setOffsetToLastSection()
        if checkVertical:
            self.verticalHeader().setOffsetToLastSection()
    # apply the fix
    QTableView.resizeEvent = resizeEventFix
    

    当使用在 Designer 中创建的 UI 时,上述技巧实际上非常有用,因为它允许修复/修补标准 Qt 类而无需总是提升它们:只要对象是使用公共函数创建的(调用 可以 被 PyQt 拦截,而不是 Qt 使用私有方法创建的对象),这些类将始终被“修补”。在这种情况下,它对于建议的测试也很有用,您可以在 Designer 中创建一定数量的可能表,然后根据上述修复轻松测试它们。

    【讨论】:

    • 我不知道 ScrollPerItem 和 ScrollPerPixel,每个像素都可以解决问题,因为我不需要特定的滚动方法。谢谢你的解释!
    • @Rodolphe 在研究特定类的文档并查找其功能时,请始终记住查找它继承自的类(可能达到“顶级”继承级别,即所有的 QObject小部件)和所有成员的列表(还包括继承的函数、属性、标志等):它们位于类页面的顶部。比如滚动模式不在QTreeWidget页面,也不在QTreeView,而是在所有项目视图的基类QAbstractItemView中,这一点很重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 2012-01-25
    • 1970-01-01
    • 2020-05-20
    • 2018-11-19
    相关资源
    最近更新 更多