组合框更改时更新 QAbstractTableModel

Update QAbstractTableModel when combobox changed

我正在尝试在更改组合框时更新我的​​模型。我有一个连接到更新模型的组合框的函数,但是来自 - “代表应该在提供标准行为时使用模型的基本函数(访问 index.model()._data 不好)”。我还希望组合框的更改能够影响 QLineEdit 中出现的内容。

QItemDelegate:

class Delegate(QItemDelegate):

    def __init__(self):
        QItemDelegate.__init__(self)
        self.type_items = ["1", "2"]

    def createEditor(self, parent, option, index):
        if index.column() == 0:
            comboBox = QComboBox(parent)
            for text in self.type_items:
                comboBox.addItem(text, (index.row(), index.column()))
                comboBox.currentIndexChanged.connect(lambda: self.comboBoxChanged(comboBox, index))
            return comboBox
        return super().createEditor(parent, option, index)

    # updates model but does not update view - shows what I want to happen
    def comboBoxChanged(self, comboBox, index):
        if comboBox.currentText() == "1":
            index.model()._data[index.row()][0] = "1"
            index.model()._data[index.row()][1] = "One"
        elif comboBox.currentText() == "2":
            index.model()._data[index.row()][0] = "2"
            index.model()._data[index.row()][1] = "Two"
        # self.dataChanged.emit(index, index) # can't call this here

QAbstractTableModel:

class TableModel(QAbstractTableModel):
    def __init__(self, data):
        super(TableModel, self).__init__()
        self._data = data

    def data(self, index, role):
        if role in (Qt.DisplayRole, Qt.EditRole):
            return self._data[index.row()][index.column()]

    def rowCount(self, index=None):
        return len(self._data)

    def columnCount(self, index=None):
        return len(self._data[0])

    def flags(self, index):
        return super().flags(index) | Qt.ItemIsEditable

    def setData(self, index, value, role=Qt.EditRole):
        if role == Qt.EditRole:
            self._data[index.row()][index.column()] = value
            self.dataChanged.emit(index, index)
            return True
        return False

主要:

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        localWidget = QWidget()

        self.table = QTableView()

        data = [["1", "One"]]

        self.model = TableModel(data)
        self.table.setModel(self.model)
        self.table.setItemDelegate(Delegate())

        self.print_data = QPushButton("Print data")
        self.print_data.clicked.connect(self.printData)

        for row in range(self.model.rowCount()):
            for column in range(self.model.columnCount()):
                index = self.model.index(row, column)
                self.table.openPersistentEditor(index)

        layout_v = QVBoxLayout()
        layout_v.addWidget(self.table)
        layout_v.addWidget(self.print_data)
        localWidget.setLayout(layout_v)
        self.setCentralWidget(localWidget)
        self.show()

    def printData(self):
        print(self.model._data)

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
  1. 如何在 qcombobox 中注册更改以正确更新模型? 和
  2. 如何使它触发 qlineedit 中的更改?

最好使用现有的 setData 功能来更新模型的数据,该功能提供了一个集中的界面,可以避免混淆错误和错误。

你的情况需要设置sibling索引的数据,即下一列同一行的索引(不需要设置索引值本身,因为 Qt 能够从组合中自动获取它,无论如何都应该在 setModelData() 中完成)。

    def comboBoxChanged(self, comboBox, index):
        if comboBox.currentText() == "1":
            value = "One"
        elif comboBox.currentText() == "2":
            value = "Two"
        sibling = index.sibling(index.row(), 1)
        index.model().setData(sibling, value)

需要说明的是,您的代码本来可以工作,但 dataChanged 模型 的信号,而不是代表的信号,因此它应该是:

        index.model().dataChanged.emit(index, index)

但是,如前所述,最好避免使用不同的方式更改模型中的数据,尤其是从模型外部完成时。使用单个函数来处理这个问题的主要好处是,每当模型的结构和实现发生变化时,唯一需要检查的就是该函数调用的所有出现(以防列顺序发生变化,例如)。