python - PyQt:如何调整 QTableView header-size/column-width

标签 python pyqt pyqt5 qtableview column-width

我正在尝试按照 link 中的说明设置标题大小或列宽.

问题是:

  1. table.horizo​​ntalHeader().setStretchLastSection(True) 可以但不是最优的

  2. self.produktKaufTb.setColumnWidth(1, 80)
    self.produktKaufTb.horizontalHeader().setResizeMode(0, QHeaderView.Stretch) 
    

    returns "AttributeError: 'QHeaderView' object has no attribute'setResizeMode'"

  3. 其他两个选项

    .horizontalHeader().setSectionResizeMode(1) 
    

    .horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) 
    

    不允许用鼠标调整列的大小

如何在 PyQt5 中设置列​​宽?

最佳答案

经过一番折腾后,我想出了一个解决方案(可能不是最优的,但希望能有所帮助)。

第 1 步:我必须子类化 QHeaderView 类并重写 resizeEvent() 函数,我从 here 得到它, 但他正在重写 TableView 的功能,而我正在重写 HeaderView。

第 2 步:然后我将 headerview 的 sectionResized 连接到一个新函数来处理列的大小调整。我希望能够在保持总宽度不变的同时调整特定列的大小,为此,当我缩小一列时,我将下一列扩展相同的量,反之亦然。我以为我不需要第 2 步就可以工作,但事实证明这是必要的。

在这个工作示例下方,我添加了一个水平拆分器,以便您可以试验表格大小调整功能。

import sys
from PyQt5 import QtWidgets
from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant

class TableModel(QAbstractTableModel):
    def __init__(self, parent, datain, headerdata):
        QAbstractTableModel.__init__(self, parent)

        self.arraydata=datain
        self.headerdata=headerdata

    def rowCount(self,p):
        return len(self.arraydata)

    def columnCount(self,p):
        if len(self.arraydata)>0:
            return len(self.arraydata[0])
        return 0

    def data(self, index, role):
        if not index.isValid():
            return QVariant()
        elif role != Qt.DisplayRole:
            return QVariant()
        return QVariant(self.arraydata[index.row()][index.column()])

    def headerData(self, col, orientation, role):
        if orientation==Qt.Horizontal and role==Qt.DisplayRole:
            return self.headerdata[col]
        return None

class MyHeaderView(QtWidgets.QHeaderView):
    def __init__(self,parent):
        QtWidgets.QHeaderView.__init__(self,Qt.Horizontal,parent)
        self.sectionResized.connect(self.myresize)

    def myresize(self, *args):
        '''Resize while keep total width constant'''

        # keep a copy of column widths
        ws=[]
        for c in range(self.count()):
            wii=self.sectionSize(c)
            ws.append(wii)

        if args[0]>0 or args[0]<self.count():
            for ii in range(args[0],self.count()):
                if ii==args[0]:
                    # resize present column
                    self.resizeSection(ii,args[2])
                elif ii==args[0]+1:
                    # if present column expands, shrink the one to the right
                    self.resizeSection(ii,ws[ii]-(args[2]-args[1]))
                else:
                    # keep all others as they were
                    self.resizeSection(ii,ws[ii])

    def resizeEvent(self, event):
        """Resize table as a whole, need this to enable resizing"""

        super(QtWidgets.QHeaderView, self).resizeEvent(event)
        self.setSectionResizeMode(1,QtWidgets.QHeaderView.Stretch)
        for column in range(self.count()):
            self.setSectionResizeMode(column, QtWidgets.QHeaderView.Stretch)
            width = self.sectionSize(column)
            self.setSectionResizeMode(column, QtWidgets.QHeaderView.Interactive)
            self.resizeSection(column, width)

        return

class MainFrame(QtWidgets.QWidget):

    def __init__(self):
        super(MainFrame,self).__init__()
        self.initUI()

    def initUI(self):

        self.doc_table=self.createTable()
        dummy_box=QtWidgets.QLineEdit()

        hlayout=QtWidgets.QHBoxLayout()
        h_split=QtWidgets.QSplitter(Qt.Horizontal)
        h_split.addWidget(self.doc_table)
        h_split.addWidget(dummy_box)
        hlayout.addWidget(h_split)
        self.setLayout(hlayout)
        self.show()

    def createTable(self):
        # create some dummy data
        self.tabledata=[['aaa' ,' title1', True, 1999],
                    ['bbb' ,' title2', True, 2000],
                    ['ccc' ,' title3', False, 2001]
                    ]
        header=['author', 'title', 'read', 'year']

        tablemodel=TableModel(self,self.tabledata,header)
        tv=QtWidgets.QTableView(self)
        hh=MyHeaderView(self)
        tv.setHorizontalHeader(hh)
        tv.setModel(tablemodel)
        tv.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        tv.setShowGrid(True)

        hh.setSectionsMovable(True)
        hh.setStretchLastSection(False)
        # this may be optional:
        #hh.setSectionResizeMode(QtWidgets.QHeaderView.Stretch)

        return tv


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super(MainWindow,self).__init__()

        self.main_frame=MainFrame()
        self.setCentralWidget(self.main_frame)
        self.setGeometry(100,100,800,600)
        self.show()


if __name__=='__main__':

    app=QtWidgets.QApplication(sys.argv)
    mainwindow=MainWindow()
    sys.exit(app.exec_())

关于python - PyQt:如何调整 QTableView header-size/column-width,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46715061/

相关文章:

python - 我想创建新的数据框列循环遍历特定列的行

python - 如果定义了 itemchange(),则无法将项目添加到项目组 (PyQt)

python - PyQt matplotlib 在图片顶部绘制轮廓数据 - 缩放问题

python - 使用 PyQt5/Pyside2 设置重复的 SVG 图案作为主窗口/Qwidget 背景

python - 用户如何向 QDoubleSpinBox 输入无穷大值?

python - 禁用编辑 QLineEdit

python - 使用 win32gui python 获取应用程序的图像名称

python - 使用ast.literal_eval()清理数据时出现语法错误

python - 为什么 Python filelock 库在 Windows 而不是 UNIX 上删除锁定文件?

python - PySide 或 PyQt 的 QtSingleApplication