通过qcombobox currentText对qtablewidget进行排序

时间:2015-09-03 22:42:18

标签: python sorting pyside qtablewidget qcombobox

我有一个qtablewidget,每行中有一个单元格小部件是qcombobox。我想根据每行qcomboboxes的内容对表格进行排序。怎么做?非常感谢任何帮助。

self.table = QTableWidget(0,5)
self.table.setSortingEnabled(True)
self.table.horizontalHeader().sortIndicatorChanged.connect(self.table_sorting_clicked)

'''some code here'''

def table_sorting_clicked(self,logicalIndex,order):

'''some code here'''

1 个答案:

答案 0 :(得分:0)

  • 安装QSignalMapper
  • 将其连接到排序方法
  • connect currentTextChanged() - 组合框的信号与signalmapper
  • 并将具有组合框的单元格的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)