组合框更改时更新 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_())
- 如何在 qcombobox 中注册更改以正确更新模型?
和
- 如何使它触发 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)
但是,如前所述,最好避免使用不同的方式更改模型中的数据,尤其是从模型外部完成时。使用单个函数来处理这个问题的主要好处是,每当模型的结构和实现发生变化时,唯一需要检查的就是该函数调用的所有出现(以防列顺序发生变化,例如)。
我正在尝试在更改组合框时更新我的模型。我有一个连接到更新模型的组合框的函数,但是来自
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_())
- 如何在 qcombobox 中注册更改以正确更新模型? 和
- 如何使它触发 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)
但是,如前所述,最好避免使用不同的方式更改模型中的数据,尤其是从模型外部完成时。使用单个函数来处理这个问题的主要好处是,每当模型的结构和实现发生变化时,唯一需要检查的就是该函数调用的所有出现(以防列顺序发生变化,例如)。