【问题标题】:Add combobox to horizontal header in QTableWidget将组合框添加到 QTableWidget 中的水平标题
【发布时间】:2019-01-22 09:38:59
【问题描述】:

我想在 PyQt5 中创建一个表,在每个列标题中都有一个组合框。当我尝试这样做时,返回以下错误:

TypeError: setHorizontalHeaderItem(self, int, QTableWidgetItem): argument 2 has unexpected type 'QComboBox'

显然setHorizontalHeaderItem() 函数不接受小部件作为项目。那么有没有办法实现这一目标?如果没有,我会解决将组合框放在标题 above 上,但它们应该与每列的大小对齐,即使用户使用鼠标更改宽度也是如此。我也不知道这是否可行。

我的代码:

from PyQt5 import QtWidgets 
import numpy as np

class App(QtWidgets.QWidget):
    def __init__(self):
        super(App,self).__init__()
        self.data = np.random.rand(5,5)
        self.createTable()
        self.layout = QtWidgets.QVBoxLayout()
        self.layout.addWidget(self.table) 
        self.setLayout(self.layout) 
        self.showMaximized()

    def createTable(self):
        self.header = []
        self.table = QtWidgets.QTableWidget(len(self.data), len(self.data[0]))
        for i in range(len(self.data[0])):
            self.header.append(QtWidgets.QComboBox())
            self.header[-1].addItem('Variable')
            self.header[-1].addItem('Timestamp')
            self.table.setHorizontalHeaderItem(i,self.header[-1])
        for i in range(len(self.data)):
            for j in range(len(self.data[0])):
                self.table.setItem(i,j,QtWidgets.QTableWidgetItem(str(self.data[i][j])))

if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    ex = App()
    app.exec_()

【问题讨论】:

    标签: python pyqt pyqt5 qtablewidget qcombobox


    【解决方案1】:

    QHeaderView 不支持将小部件作为项目,因此您必须创建一个自定义标题,如下所示:

    from PyQt5 import QtCore, QtWidgets 
    import numpy as np
    
    class HorizontalHeader(QtWidgets.QHeaderView):
        def __init__(self, values, parent=None):
            super(HorizontalHeader, self).__init__(QtCore.Qt.Horizontal, parent)
            self.setSectionsMovable(True)
            self.comboboxes = []
            self.sectionResized.connect(self.handleSectionResized)
            self.sectionMoved.connect(self.handleSectionMoved)
    
        def showEvent(self, event):
            for i in range(self.count()):
                if i < len(self.comboboxes):
                    combo = self.comboboxes[i]
                    combo.clear()
                    combo.addItems(["Variable", "Timestamp"])
                else:
                    combo = QtWidgets.QComboBox(self)
                    combo.addItems(["Variable", "Timestamp"])
                    self.comboboxes.append(combo)
    
                combo.setGeometry(self.sectionViewportPosition(i), 0, self.sectionSize(i)-4, self.height())
                combo.show()
    
            if len(self.comboboxes) > self.count():
                for i in range(self.count(), len(self.comboboxes)):
                    self.comboboxes[i].deleteLater()
    
            super(HorizontalHeader, self).showEvent(event)
    
        def handleSectionResized(self, i):
            for i in range(self.count()):
                j = self.visualIndex(i)
                logical = self.logicalIndex(j)
                self.comboboxes[i].setGeometry(self.sectionViewportPosition(logical), 0, self.sectionSize(logical)-4, self.height())
    
        def handleSectionMoved(self, i, oldVisualIndex, newVisualIndex):
            for i in range(min(oldVisualIndex, newVisualIndex), self.count()):
                logical = self.logicalIndex(i)
                self.comboboxes[i].setGeometry(self.ectionViewportPosition(logical), 0, self.sectionSize(logical) - 5, height())
    
        def fixComboPositions(self):
            for i in range(self.count()):
                self.comboboxes[i].setGeometry(self.sectionViewportPosition(i), 0, self.sectionSize(i) - 5, self.height())
    
    class TableWidget(QtWidgets.QTableWidget):
        def __init__(self, *args, **kwargs):
            super(TableWidget, self).__init__(*args, **kwargs)
            header = HorizontalHeader(self)
            self.setHorizontalHeader(header)
    
        def scrollContentsBy(self, dx, dy):
            super(TableWidget, self).scrollContentsBy(dx, dy)
            if dx != 0:
                self.horizontalHeader().fixComboPositions()
    
    
    class App(QtWidgets.QWidget):
        def __init__(self):
            super(App,self).__init__()
            self.data = np.random.rand(10, 10)
            self.createTable()
            layout = QtWidgets.QVBoxLayout(self)
            layout.addWidget(self.table) 
            self.showMaximized()
    
        def createTable(self):
            self.header = []
            self.table = TableWidget(*self.data.shape)
            for i, row_values in enumerate(self.data):
                for j, value in enumerate(row_values):
                    self.table.setItem(i, j, QtWidgets.QTableWidgetItem(str(value)))
    
    if __name__ == '__main__':
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        ex = App()
        sys.exit(app.exec_())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 2013-10-12
      • 2016-11-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多