- 安装
QSignalMapper
- 连接到排序方法
- 将组合框的
currentTextChanged()-signal 与信号映射器连接
- 并将带有组合框的单元格的 itemData 设置为
currentText()(必须的,因为如果所有单元格都只包含组合框,则无需排序)
- 如果
currentText() 发生变化,则更新 itemData。
这里是 pyqt5 中的一个工作示例:
class MyTableWidget(QtWidgets.QTableWidget):
def __init__(self, parent = None):
QtWidgets.QTableWidget.__init__(self, parent)
self.setRowCount(5)
self.setColumnCount(2)
self.signalMapper = QtCore.QSignalMapper(self)
self.signalMapper.mapped.connect(self.table_sorting_clicked)
self.horizontalHeader().sortIndicatorChanged.connect(self.changeSortOrder)
texts = []
for i in ['A','B','C','D','E','F','G','H','I','J']:
texts.append(i)
for i in range(0,self.rowCount()):
combo = QtWidgets.QComboBox()
combo.addItems(texts)
combo.setCurrentIndex(i)
combo.currentTextChanged.connect(self.signalMapper.map)
self.signalMapper.setMapping(combo, i)
self.setItem(i,0,QtWidgets.QTableWidgetItem(str(i+1)))
self.setItem(i,1,QtWidgets.QTableWidgetItem())
self.setCellWidget(i,1,combo)
self.item(i,1).setData(0, combo.currentText())
self.setSortingEnabled(True)
self.sortOrder = 0
def table_sorting_clicked(self, index):
self.item(index,1).setData(0, self.cellWidget(index,1).currentText())
self.sortByColumn(1,self.sortOrder)
# edit 04.09.2015 19:40
#this doesn't work correctly if called several times
# add the following code:
for i in range(self.rowCount()):
self.signalMapper.removeMappings(self.cellWidget(i,1))
self.cellWidget(i,1).currentTextChanged.connect(self.signalMapper.map)
self.signalMapper.setMapping(self.cellWidget(i,1), i)
def changeSortOrder(self,logicalIndex,order):
self.sortOrder = order
self.sortByColumn(logicalIndex,self.sortOrder)
但对于您的目的而言,使用委托可能是更好的选择。在那里您可以将 QListWidget 设置为用户的编辑器/选择器,并且您不需要另外设置项目数据,信号会更简单:
class MyDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, t, parent=None,):
QtWidgets.QStyledItemDelegate.__init__(self)
self.setParent(parent)
self.editorTexte = t
def createEditor(self,parent, option, index):
if index.column() == 1:
return QtWidgets.QListWidget(parent)
return QtWidgets.QStyledItemDelegate.createEditor(self,parent, option, index)
def setEditorData(self, editor, index):
value = str(index.data())
if index.column() == 1:
for i, v in enumerate(self.editorTexte):
item = QtWidgets.QListWidgetItem(v)
editor.addItem(item)
if v == value:
editor.setCurrentItem(editor.item(i))
x = self.parent().columnViewportPosition(index.column())
y = self.parent().rowViewportPosition(index.row())
w = self.parent().columnWidth(index.column())
h = self.parent().rowHeight(index.row())*5
editor.setGeometry(x,y,w,h)
else:
QtWidgets.QStyledItemDelegate.setEditorData(self, editor, index)
def setModelData(self,editor,model,index):
if index.column() == 1:
v = editor.currentItem().text()
else:
v = editor.text()
model.setData(index, v)
class MyTableWidget(QtWidgets.QTableWidget):
def __init__(self, parent = None):
QtWidgets.QTableWidget.__init__(self, parent)
self.setRowCount(5)
self.setColumnCount(2)
texts = []
for i in ['A','B','C','D','E','F','G','H','I','J']:
texts.append(i)
self.setItemDelegate(MyDelegate(texts, self))
for i in range(0,self.rowCount()):
self.setItem(i,0,QtWidgets.QTableWidgetItem(str(i+1)))
self.setItem(i,1,QtWidgets.QTableWidgetItem(texts[i]))
self.setSortingEnabled(True)
self.sortOrder = 0
self.sortByColumn(1,self.sortOrder)
self.horizontalHeader().sortIndicatorChanged.connect(self.changeSortOrder)
def changeSortOrder(self,logicalIndex,order):
self.sortOrder = order
self.sortByColumn(logicalIndex,self.sortOrder)