Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 具有相对宽度、可伸缩列的QTableWidget_Python_Pyqt_Pyqt5_Qtablewidget - Fatal编程技术网

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

Python 具有相对宽度、可伸缩列的QTableWidget,python,pyqt,pyqt5,qtablewidget,Python,Pyqt,Pyqt5,Qtablewidget,我正在尝试实现一个类似于以下表的pyqt5表: 首先:我甚至不确定QTableWidget是否是最合适的widget,因为我对Qt没有太多经验。QGridLayout可能更适合。我先尝试了一下,但不知何故,我不知道如何使它符合要求,任何建议都将不胜感激 表格要求如下: 一些单元格包含文本、一些QCheckbox和一些QRadioButtons 在调整表的大小时,表的宽度必须始终占其父表宽度的100%(我当前使用的是setSectionResizeMode(QHeaderView.Stretc

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

首先:我甚至不确定QTableWidget是否是最合适的widget,因为我对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_()

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

您缺少的是属性:

如果此属性设置为false(默认值),则滚动区域将按照其小部件的大小显示

[…]如果此属性设置为true,滚动区域将自动调整小部件的大小,以避免滚动条出现在可以避免的地方,或利用额外的空间

然后,您不应该使用列范围来确保小部件自行扩展,而是应该使用列范围

最后,为确保滚动区域始终显示内容而不“剪切”右侧,不应禁用水平滚动条,而是应根据区域内容、垂直滚动条宽度和滚动区域框架宽度正确设置最小宽度

考虑到所有这些,您显然不需要再设置网格最小宽度

    # Grid elements
    for i in range(20):
        self.gridLayout.addWidget(QPushButton('A'), i, 0)
        self.gridLayout.addWidget(QPushButton('B'), i, 1)
        self.gridLayout.addWidget(QPushButton('C'), i, 2)
    # ensure that the second column uses a stretch factor bigger than the
    # default 0 value (which will only honor the size hints and policies of
    # each widget
    self.gridLayout.setColumnStretch(1, 1)

    # Scroll area
    self.scrollArea = QScrollArea()
    self.scrollArea.setWidget(self.grid)
    self.scrollArea.setWidgetResizable(True)
    # compute the correct minimum width
    width = (self.grid.sizeHint().width() + 
        self.scrollArea.verticalScrollBar().sizeHint().width() + 
        self.scrollArea.frameWidth() * 2)
    self.scrollArea.setMinimumWidth(width)

你确定你真的需要一张桌子吗?如果您不需要项目视图的功能,而只想找到一种将标签和复选框/收音机对齐的方法,那么您不能在QScrolla区域内使用一个带有QGridLayout集的普通QWidget吗?(顺便说一句,QGridView从Qt4起就不存在了)。列的大小是否可以调整?这张桌子可以调整大小吗?“项目”是否应始终占据整个可用空间?您是否考虑过对单个列使用,而不是对所有列进行设置?@musicamante好的,这是一个输入错误(我指的是QGridLayout,不是QGridView)。GridLayout是我的第一次尝试(在我的问题的新版本中添加了这个示例),但是当窗口大小改变时,我无法调整列的大小。是的,列的大小应该是可调整的,网格或表格应该占据所有宽度。我建议您编辑您的文章,并提供您对QGridLayout的尝试,因为这可能是更实际的选择。@musicamante我刚才就是这么做的。抱歉,我没有得到编辑。我刚刚发布了一个使用网格布局方法的答案。谢谢你的回答。我看到现在至少内容没有被剪裁,并且填充了父级的宽度。但仍然存在两个问题:第一列和第三列没有扩展,但宽度固定,如果我在所有列中都使用setColumnStretch,那么所有列的宽度都相同。我看到的第二个问题是,如果没有grid.setMinimumWidth,在窗口宽度较小的情况下,三列的宽度也设置为相等。我可以使用setColumnStretch和不同的因子来保持列宽比以解决第一个问题。根据小部件的不同,它们总是尽可能小,因此,如果它们的类型相同,内容相似,它们的最小宽度总是相同的。您可以通过使用设置(可能是任意的)最小宽度来避免这种情况。
    # Grid elements
    for i in range(20):
        self.gridLayout.addWidget(QPushButton('A'), i, 0)
        self.gridLayout.addWidget(QPushButton('B'), i, 1)
        self.gridLayout.addWidget(QPushButton('C'), i, 2)
    # ensure that the second column uses a stretch factor bigger than the
    # default 0 value (which will only honor the size hints and policies of
    # each widget
    self.gridLayout.setColumnStretch(1, 1)

    # Scroll area
    self.scrollArea = QScrollArea()
    self.scrollArea.setWidget(self.grid)
    self.scrollArea.setWidgetResizable(True)
    # compute the correct minimum width
    width = (self.grid.sizeHint().width() + 
        self.scrollArea.verticalScrollBar().sizeHint().width() + 
        self.scrollArea.frameWidth() * 2)
    self.scrollArea.setMinimumWidth(width)