Python 将组合框添加到QTableWidget中的水平标题

Python 将组合框添加到QTableWidget中的水平标题,python,pyqt,pyqt5,qtablewidget,qcombobox,Python,Pyqt,Pyqt5,Qtablewidget,Qcombobox,我想在PyQt5中创建一个表,每个列标题中都有一个组合框。当我尝试执行此操作时,返回以下错误: TypeError:setHorizontalHeaderItem(self、int、QTableWidgetItem):参数2具有意外的类型“QComboBox” 显然,函数setHorizontalHeaderItem()不接受小部件作为项目。那么有没有办法做到这一点呢?如果没有,我会将组合框放在标题上方,但它们应该与每列的大小对齐,即使用户用鼠标更改宽度。我也不知道这是否可行 我的代码: fro

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

TypeError:setHorizontalHeaderItem(self、int、QTableWidgetItem):参数2具有意外的类型“QComboBox”

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

我的代码:

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_()

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_())
从PyQt5导入QtCore、QtWidgets
将numpy作为np导入
类HorizontalHeader(qtwidts.QHeaderView):
def uuu init uuu(self,values,parent=None):
超级(水平头,自我)。\uuuu初始化(QtCore.Qt.Horizontal,父级)
self.setSectionsMovable(真)
self.combobox=[]
self.section已调整大小.connect(self.handlesection已调整大小)
self.sectionMoved.connect(self.handleSectionMoved)
def showEvent(自我、事件):
对于范围内的i(self.count()):
如果iself.count():
对于范围内的i(self.count(),len(self.combobox)):
self.combobox[i].deleteLater()
超级(水平标题,自我)。showEvent(事件)
def handleSectionResized(自我,i):
对于范围内的i(self.count()):
j=自身视觉指数(i)
逻辑=自身。逻辑索引(j)
self.ComboBox[i].setGeometry(self.sectionViewportPosition(逻辑)、0、self.sectionSize(逻辑)-4、self.height())
def handleSectionMoved(自身、i、旧VisualIndex、新VisualIndex):
对于范围内的i(min(oldVisualIndex,newVisualIndex),self.count()):
逻辑=自身。逻辑索引(i)
self.ComboBox[i].setGeometry(self.ViewPortPosition(逻辑)、0、self.sectionSize(逻辑)-5、height())
def固定位置(自身):
对于范围内的i(self.count()):
self.ComboBox[i].setGeometry(self.sectionViewportPosition(i),0,self.sectionSize(i)-5,self.height())
类TableWidget(QtWidgets.QTableWidget):
定义初始化(self,*args,**kwargs):
super(TableWidget,self)。\uuuuuuu初始化(*args,**kwargs)
收割台=水平收割台(自身)
self.setHorizontalHeader(标题)
def scrollContentsBy(自身、dx、dy):
super(TableWidget,self).scrollContentsBy(dx,dy)
如果dx!=0:
self.horizontalHeader().fixComboPositions()
类应用程序(qtwidts.QWidget):
定义初始化(自):
超级(应用程序,自我)。\uuuu初始化
self.data=np.rand.rand(10,10)
self.createTable()
layout=qtwidts.QVBoxLayout(self)
layout.addWidget(self.table)
self.showmized()
def createTable(自):
self.header=[]
self.table=TableWidget(*self.data.shape)
对于i,枚举(self.data)中的行_值:
对于j,枚举中的值(行值):
self.table.setItem(i,j,QtWidgets.QTableWidgetItem(str(value)))
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
导入系统
app=qtwidts.QApplication(sys.argv)
ex=App()
sys.exit(app.exec_())

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_())
从PyQt5导入QtCore、QtWidgets
将numpy作为np导入
类HorizontalHeader(qtwidts.QHeaderView):
def uuu init uuu(self,values,parent=None):
超级(水平头,自我)。\uuuu初始化(QtCore.Qt.Horizontal,父级)
self.setSectionsMovable(真)
self.combobox=[]
self.section已调整大小.connect(self.handlesection已调整大小)
self.sectionMoved.connect(self.handleSectionMoved)
def showEvent(自我、事件):
对于范围内的i(self.count()):
如果iself.count():
对于范围内的i(self.count(),len(self.combobox)):
self.combobox[i].deleteLater()
超级(水平标题,自我)。showEvent(事件)
def handleSectionResized(自我,i):
对于范围内的i(self.count()):
j=自身视觉指数(i)
逻辑=自身。逻辑索引(j)
self.ComboBox[i].setGeometry(self.sectionViewportPosition(逻辑)、0、self.sectionSize(逻辑)-4、self.height())
def handleSectionMoved(自身、i、旧VisualIndex、新VisualIndex):
对于范围内的i(min(oldVisualIndex,newVisualIndex),self.count()):
逻辑=自身。逻辑索引(i)
self.ComboBox[i].setGeometry(self.ViewPortPosition(逻辑)、0、self.sectionSize(逻辑)-5、height())
def固定位置(自身):
对于范围内的i(self.count()):
self.ComboBox[i].setGeometry(self.sectionViewportPosition(i),0,self.sectionSize(i)-5,self.height())
类TableWidget(QtWidgets.QTableWidget):
def__英寸