簡體   English   中英

更改 QTableWidget 項目數據以獲得正確的行

[英]Change QTableWidget Item data for correct row

啟用排序時,如何正確更新 QTableWidget 中特定行的數據。 我注意到當我更改啟用排序的列的數據時,行會立即重新排序,結果第二列的數據被放置在錯誤的行中。

這是開始的屏幕截圖:

在此處輸入圖片說明

接下來,我雙擊 C 行以進行編輯,如下所示:

在此處輸入圖片說明

現在您將看到它正確更改了第 0 列中的數據以顯示 ZZZ,但是第二列文本現在位於錯誤的行中。 我怎樣才能解決這個問題?

在此處輸入圖片說明

import os, sys, json
from PySide import QtGui, QtCore


class TokenEditorDialog(QtGui.QDialog):

    def __init__(self, key, value, parent=None):
        super(TokenEditorDialog, self).__init__(parent)
        self.resize(300,50)

        self.uiKey = QtGui.QLineEdit(key)
        self.uiValue = QtGui.QLineEdit(value)

        self.uiOk = QtGui.QPushButton('OK')
        self.uiCancel = QtGui.QPushButton('Cancel')

        self.uiButtons = QtGui.QDialogButtonBox()
        self.uiButtons.addButton(self.uiOk, QtGui.QDialogButtonBox.ActionRole)
        self.uiButtons.addButton(self.uiCancel, QtGui.QDialogButtonBox.ActionRole)

        self.layout = QtGui.QFormLayout()
        self.layout.addRow('Key', self.uiKey)
        self.layout.addRow('Value', self.uiValue)
        self.layout.addWidget(self.uiButtons)
        self.setLayout(self.layout)

        # connections
        self.uiOk.clicked.connect(self.accept)
        self.uiCancel.clicked.connect(self.close)


class TokenEditorWidget(QtGui.QWidget):

    def __init__(self, tokens, parent=None):
        super(TokenEditorWidget, self).__init__(parent)
        self.resize(400, 400)
        self.setWindowTitle('Token Editor')

        # privates
        self.uiView = QtGui.QTableWidget()
        self.uiView.setSortingEnabled(True)
        self.uiView.setAlternatingRowColors(True)
        self.uiView.verticalHeader().hide()
        self.uiView.horizontalHeader().show()
        self.uiView.setShowGrid(False)
        self.uiView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.uiView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self.uiView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)

        self.selection = self.uiView.selectionModel()

        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.uiView)
        self.setLayout(self.layout)

        self.createActions()
        self.createMenus()

        # connections
        self.selection.selectionChanged.connect(self.updateControls)
        self.uiView.itemDoubleClicked.connect(self.editSelectedItem)
        self.uiView.customContextMenuRequested.connect(self.showContextMenu)

        # initialize
        self.setTokens(tokens)
        self.updateControls()


    def setTokens(self, tokens):
        '''
        Description:
            Loop through tuples and append table
        '''
        self.uiView.setColumnCount(2)
        self.uiView.setRowCount(0)
        self.uiView.setHorizontalHeaderLabels(['Key', 'Value'])
        for k, v in tokens:
            rowIndex = self.uiView.rowCount()
            self.uiView.insertRow(rowIndex)
            self.uiView.setItem(rowIndex, 0, QtGui.QTableWidgetItem(k))
            self.uiView.setItem(rowIndex, 1, QtGui.QTableWidgetItem(v))
        self.uiView.resizeColumnsToContents()
        self.uiView.sortByColumn(0, QtCore.Qt.AscendingOrder)
        self.uiView.horizontalHeader().setStretchLastSection(True)


    def updateControls(self):
        state = len(self.selection.selectedRows())

        self.act_remove.setEnabled( state >= 1)
        self.act_edit.setEnabled( state == 1)


    def createActions(self):
        self.act_add = QtGui.QAction('Add New...', self)
        # self.act_add.triggered.connect(self.saveHotkeysPreset)

        self.act_edit = QtGui.QAction('Edit...', self)
        self.act_edit.triggered.connect(self.editSelectedItem)

        self.act_remove = QtGui.QAction('Remove', self)
        self.act_remove.triggered.connect(self.removeSelectedItems)

        self.act_clear = QtGui.QAction('Clear', self)
        self.act_clear.triggered.connect(self.clearItems)


    def createMenus(self):
        self.file_menu = QtGui.QMenu('File')
        self.file_menu.addAction(self.act_add)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.act_edit)
        self.file_menu.addAction(self.act_remove)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.act_clear)
        # self.menuBar().addMenu(self.file_menu)

        menuBar = QtGui.QMenuBar(self)
        menuBar.addMenu(self.file_menu)
        self.layout.setMenuBar(menuBar)


    def removeSelectedItems(self):
        indices = []

        selectedRows = self.selection.selectedRows()
        for x in selectedRows:
            indices.append(QtCore.QPersistentModelIndex(x))

        for x in indices:
            self.uiView.removeRow(x.row())


    def clearItems(self):
        self.setTokens([])


    def showContextMenu(self):
        self.file_menu.exec_(QtGui.QCursor.pos())


    def editSelectedItem(self):
        selectedRows = self.selection.selectedRows()
        if selectedRows:
            # rowIndex = QtCore.QPersistentModelIndex(selectedRows[0])
            rowIndex = selectedRows[0].row()

            key = self.uiView.item(rowIndex, 0).text()
            value = self.uiView.item(rowIndex, 1).text()

            dlg = TokenEditorDialog(key, value, parent=self)
            if dlg.exec_():
                self.uiView.item(rowIndex, 0).setText(dlg.uiKey.text())
                self.uiView.item(rowIndex, 1).setText(dlg.uiValue.text())


def main():
    app = QtGui.QApplication(sys.argv)
    ex = TokenEditorWidget(
        tokens=[
            ('A', 'Description'),
            ('B', 'Description'),
            ('C', 'Description'),
            ('D', 'Description'),
            ('E', 'Description'),
            ('F', 'Description'),
        ],
    )
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

我相信問題在於,當修改第一列項目時,表格執行排序,然后修改第二項。 可能信號“dataChanged”與排序有關。

我的解決方案僅限於您的代碼,這可能不是最好的方法。 我通常更喜歡為這種事情編寫自己的模型視圖類。

您只需要修改您的editSelectedItem方法,如下所示:

def editSelectedItem(self):
    selectedRows = self.selection.selectedRows()
    if selectedRows:
        # rowIndex = QtCore.QPersistentModelIndex(selectedRows[0])
        rowIndex = selectedRows[0].row()

        key = self.uiView.item(rowIndex, 0).text()
        value = self.uiView.item(rowIndex, 1).text()

        dlg = TokenEditorDialog(key, value, parent=self)
        if dlg.exec_():
            # this line retrieves the current column index of the sorting on the table
            icol = self.uiView.horizontalHeader().sortIndicatorSection()
            if icol == 0:
                self.uiView.item(rowIndex, 1).setText(dlg.uiValue.text())
                self.uiView.item(rowIndex, 0).setText(dlg.uiKey.text())
            elif icol == 1:
                self.uiView.item(rowIndex, 0).setText(dlg.uiKey.text())
                self.uiView.item(rowIndex, 1).setText(dlg.uiValue.text())
            else:
                # if you want to add more cases
                pass

我希望它有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM