具有相对宽度的可伸缩列的QTableWidget

问题描述 投票:0回答:1

我正在尝试实现类似于以下内容的pyqt5表:

enter image description here

首先:我甚至不确定QTableWidget是否是最合适的小部件,因为我对Qt的经验不足。 QGridLayout可能更适合。我先尝试了一下,但是不知为何我不知道如何使其符合要求,任何建议都将不胜感激。

表要求为:

  • 某些单元格包含文本,一些QCheckBox和一些QRadioButtons
  • 表的宽度在调整大小时必须始终填充其父宽度的100%(我目前正在使用setSectionResizeMode(QHeaderView.Stretch)
  • 表格应该可以垂直滚动
  • 其某些列的相对宽度不同,必须保持这种关系(在这里开始我的问题)
  • 每列的居中都不一样(无法在文档中找到实现方法的方法)

我当前的问题是setSectionResizeMode的使用与resizeSection冲突。我可以使用不同的列宽或可伸缩的表格宽度,但是我不知道如何实现两者。

示例代码如下:

from PyQt5.QtWidgets import QApplication, QWidget, QHeaderView, QTableWidget, QTableWidgetItem, QVBoxLayout
import sys

data = {'col1':['1','2','3','4'],
        'col2':['1','2','1','3'],
        'col3':['1','1','2','1']}


class MainWindow(QWidget):

    def __init__(self):

        super().__init__()

        self.table = QTableWidget()
        self.table.setRowCount(4)
        self.table.setColumnCount(3)
        self.table.verticalHeader().hide()
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        # self.table.horizontalHeader().resizeSection(1, 200) <-- no effect if stretch is activated

        self.table.setHorizontalHeaderLabels([colName for colName in data])
        self.fillTable()

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.table)
        self.setLayout(self.layout)


    def fillTable(self):
        for colNumber, colName in enumerate(data):
            for rowNumber, value in enumerate(data[colName]):
                self.table.setItem(rowNumber, colNumber, QTableWidgetItem(value))


if __name__=="__main__":

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

这是我的另一个尝试,使用QGridLayout。这里的问题是,调整窗口大小时,列不会展开。

import sys
from PyQt5.QtWidgets import (QWidget, QGridLayout, QLabel, QPushButton, QApplication, QScrollArea, QVBoxLayout)
from PyQt5.QtCore import Qt

class MainWindow(QWidget):

    def __init__(self):

        super().__init__()

        # Label
        self.label = QLabel('Test')

        # Grid
        self.grid = QWidget()
        self.gridLayout = QGridLayout()
        self.grid.setLayout(self.gridLayout)
        self.grid.setMinimumWidth(600) # Without this, the width relations are not kept

        # Grid elements
        for i in range(20):
            self.gridLayout.addWidget(QPushButton('A'), i, 0, 1, 1)
            self.gridLayout.addWidget(QPushButton('B'), i, 1, 1, 3)
            self.gridLayout.addWidget(QPushButton('C'), i, 4, 1, 1)

        # Scroll area
        self.scrollArea = QScrollArea()
        self.scrollArea.setWidget(self.grid)
        self.scrollArea.setMinimumWidth(self.grid.sizeHint().width())
        self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # Window layout
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.label)
        self.layout.addWidget(self.scrollArea)
        self.setLayout(self.layout)


if __name__ == '__main__':

    app = QApplication(sys.argv)
    windowExample = MainWindow()
    windowExample.show()
    sys.exit(app.exec_())
python pyqt pyqt5 qtablewidget
1个回答
0
投票

使用网格布局可能是最佳选择,因为项目视图更适合显示项目模型,并且不包含GUI元素。

您所缺少的是widgetResizable属性:

如果此属性设置为false(默认值),则滚动区域将使用其小部件的大小。

[...]如果将此属性设置为true,则滚动区域将自动调整窗口小部件的大小,以避免在可以避免滚动条的地方避免滚动条,或者利用多余的空间。

然后,您不应该使用列跨度来确保小部件自行扩展,而应使用widgetResizable

最后,要确保滚动区域始终显示内容而不会在右侧“剪切”,您不应禁用水平滚动条,而应根据区域的内容正确设置最小宽度,即垂直方向滚动条宽度和滚动区域边框宽度。

setColumnStretch
© www.soinside.com 2019 - 2024. All rights reserved.