0

这是示例代码:

from PyQt5.QtWidgets import QApplication, QTableWidget, QTableWidgetItem, \
    QMainWindow
from PyQt5.QtCore import QSize
import sys

DATA = {
    f'col{i}': [f'{i * j}' for j in range(1, 10)] for i in range(1, 10)
}


class Table(QTableWidget):
    def __init__(self, d):
        m = len(d[next(iter(d))])
        n = len(DATA)
        super().__init__(m, n)

        hor_headers = []
        for n, (key, values) in enumerate(DATA.items()):
            hor_headers.append(key)
            for m, item in enumerate(values):
                qtitem = QTableWidgetItem(item)
                self.setItem(m, n, qtitem)
        self.setHorizontalHeaderLabels(hor_headers)
        # the sizeHint works fine if I disable this line
        self.setVerticalHeaderLabels(f'row{i}' for i in range(1, m + 2))

        self.resizeColumnsToContents()
        self.resizeRowsToContents()

    # improves the situation but still the window is smaller than the table
    def sizeHint(self):
        hh = self.horizontalHeader()
        vh = self.verticalHeader()
        fw = self.frameWidth() * 2
        return QSize(
            hh.length() + vh.width() + fw,
            vh.length() + hh.height() + fw)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('<TITLE>')
        table = Table(DATA)
        self.setCentralWidget(table)
        # did not work
        # self.setFixedSize(self.layout().sizeHint())


def main(args):
    app = QApplication(args)
    main_win = MainWindow()
    main_win.show()
    raise SystemExit(app.exec_())


if __name__ == "__main__":
    main(sys.argv)

结果如下:

使用 setVerticalHeaderLabels

第 9 行和第 9 列没有显示,并且有滚动条。

如果我注释掉该self.setVerticalHeaderLabels(f'row{i}' for i in range(1, m + 2))行,那么它将起作用:

没有 setVerticalHeaderLabels

如何在具有垂直标题标签的同时完美地将主窗口适合表格小部件?

正如您在代码注释中看到的那样,我已经尝试了python qt 建议的解决方案:自动调整主窗口大小以适应内容,但它们不起作用。

4

1 回答 1

1

问题在于,当像项目视图这样的复杂小部件尚未“映射”时,其子项(标题和滚动条)的实际大小尚未更新。只有当视图最终显示并可能添加到布局时,它才会再次调整自身大小,以便使用updateGeometries.

这意味着,在此之前,每个标题的大小都基于其默认的基本内容(垂直标题的行号)。

解决方案很简单:不要使用标题大小,而是使用它们的提示,这些提示是使用将要显示的实际文本计算的:

def sizeHint(self):
    hh = self.horizontalHeader()
    vh = self.verticalHeader()
    fw = self.frameWidth() * 2
    return QSize(
        hh.length() + vh.sizeHint().width() + fw,
        vh.length() + hh.sizeHint().height() + fw)
于 2021-09-02T17:51:49.167 回答