【问题标题】:PySide - PyQt : How to make set QTableWidget column width as proportion of the available space?PySide - PyQt:如何将 QTableWidget 列宽设置为可用空间的比例?
【发布时间】:2016-11-01 02:41:39
【问题描述】:

我正在使用 PySide 开发一个计算机应用程序,并且我正在使用 QTableWidget。假设我的表有 3 列,但它们包含的数据非常不同,例如(对于每一行)第一列中的长句,最后两列中的 3 位数字。我希望调整表格大小以根据数据调整其大小,或者至少能够将列大小设置为(例如)70/15/15 %的可用空间

最好的方法是什么?

我在阅读this question 后尝试了table.horizontalHeader().setResizeMode(QHeaderView.Stretch),但它会产生相同大小的 3 列。

感谢Fabiocomment,我也尝试了table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents),但它并没有根据需要填满所有可用空间。

QHeaderView documentation 中的InteractiveFixedStretchResizeToContents 似乎都不能满足我的需求(参见第二次编辑)。

任何帮助都将不胜感激,即使它是针对 Qt/C++ 的!非常感谢。


编辑:我找到了一种解决方法,但它仍然不是我想要的:

header = table.horizontalHeader()
header.setResizeMode(QHeaderView.ResizeToContents)
header.setStretchLastSection(True)

如果有setStretchFirstSection方法就更好了,可惜好像没有。


编辑 2:

表格中唯一可以修改的是最后一列,用户可以在其中输入一个数字。红色箭头表示我想要的。

Stretch 会发生以下情况

ResizeToContents 会发生以下情况

【问题讨论】:

  • 尝试 QHeaderView.ResizeToContents 而不是 QHeaderView.Stretch
  • 这行得通,但这不是我想要的,因为ResizeToContents,因为我的列不够大,它们没有填满可用的空间。我将进行编辑,使其变得更加清晰。
  • 对于您的第二次编辑,我认为正确的做法是根据您的粗略估计将列设置为默认宽度,然后由于可以拉伸,用户可以稍后根据需要对其进行修改。

标签: python qt user-interface pyqt pyside


【解决方案1】:

这可以通过为每列设置调整大小模式来解决。第一部分必须拉伸以占用可用空间,而最后两部分只是根据内容调整大小:

PyQt4:

header = self.table.horizontalHeader()
header.setResizeMode(0, QtGui.QHeaderView.Stretch)
header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents)

PyQt5:

header = self.table.horizontalHeader()       
header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)

【讨论】:

  • 我不知道我可以为每一列选择不同的QHeaderView。这很好用,尽管我将最后两列更改为 Fixed,然后使用 self.table.setColumnWidth(index, width) 添加了最小宽度(更适合我的情况)
  • 在 qt5 中这个函数改为 setSectionResizeMode()
【解决方案2】:

如前所述,您可以通过设置每列的 resize-mode 来做到这一点。但是,如果您有很多列,这可能是很多代码。我这样做的方式是将“常规”调整大小模式设置为“ResizeToContent”,而不是将一个(或多个)列设置为“拉伸”!

代码如下:

PyQt4:

header = self.table.horizontalHeader()
header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(0, QtGui.QHeaderView.Stretch)

PyQt5:

header = self.table.horizontalHeader()
header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)       
header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)

【讨论】:

    【解决方案3】:

    PyQt4

    header = self.table.horizontalHeader()
    header.setResizeMode(0, QtGui.QHeaderView.Stretch)
    header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents)
    header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents)
    header.setResizeMode(3, QtGui.QHeaderView.Stretch)
    

    PyQt5

    header = self.table.horizontalHeader()       
    header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
    header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
    header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)
    header.setSectionResizeMode(3, QtWidgets.QHeaderView.Stretch)
    

    【讨论】:

      【解决方案4】:

      您可以使用QItemDelegatesQStyledItemDelegates 执行此操作。如果要调整内容的大小并且具有自动拉伸功能,则需要选择哪一列是“拉伸”列。

      class ResizeDelegate(QStyledItemDelegate):
      
          def __init__(self, table, stretch_column, *args, **kwargs):
              super(ResizeDelegate, self).__init__(*args, **kwargs)        
              self.table = table
              self.stretch_column = stretch_column
      
          def sizeHint(self, option, index):
              size = super(ResizeDelegate, self).sizeHint(option, index)
              if index.column() == self.stretch_column:
                  total_width = self.table.viewport().size().width()
                  calc_width = size.width()
                  for i in range(self.table.columnCount()):
                      if i != index.column():
                          option_ = QtGui.QStyleOptionViewItem()
                          index_ = self.table.model().index(index.row(), i)
                          self.initStyleOption(option_, index_)
                          size_ = self.sizeHint(option_, index_)
                          calc_width += size_.width()
                  if calc_width < total_width:
                      size.setWidth(size.width() + total_width - calc_width)
              return size
      
      ...
      
      table = QTableWidget()
      delegate = ResizeDelegate(table, 0)
      table.setItemDelegate(delegate)
      ... # Add items to table
      table.resizeColumnsToContents()
      

      您可以将调整大小模式设置为ResizeToContents,或者如果您希望用户能够根据需要调整列宽,只需在更改表格项后手动调用resizeColumnsToContents即可。

      由于列之间的边距和填充,您可能还需要稍微调整宽度计算(例如为每列添加一个或两个像素到 calculated_width 以说明单元格边框)。

      【讨论】:

      • 这很好,因为现在我的列不会像以前那样随时调整大小,但它们仍然没有占用所有可用空间,并且更改“拉伸”列似乎没有任何效果...我做错了什么吗?我将使用我得到的结果编辑我的问题
      【解决方案5】:

      我用过这个,setMinumumsectionsize 解决了我的 Qtableview 单元格大小问题

      self.questionWidget.tableView.setModel(self.model)
      self.questionWidget.tableView.verticalHeader().setVisible(False)
      self.questionWidget.tableView.horizontalHeader().setMinimumSectionSize(200)
      
      

      【讨论】:

        【解决方案6】:

        我必须移除 QtWidget 才能让我的工作。

                header = self.tag_table.horizontalHeader()
                header.setSectionResizeMode(QHeaderView.ResizeToContents)
        

        【讨论】:

        • 是否需要QtWidget. 完全取决于您导入模块的方式;)
        猜你喜欢
        • 1970-01-01
        • 2021-12-22
        • 2017-01-19
        • 1970-01-01
        • 2015-11-09
        • 1970-01-01
        • 2017-12-12
        • 2015-12-13
        • 2017-04-21
        相关资源
        最近更新 更多