Python Qt模型/视图表中的按钮

Python Qt模型/视图表中的按钮,python,pyqt,pyqt5,qtableview,qabstracttablemodel,Python,Pyqt,Pyqt5,Qtableview,Qabstracttablemodel,我正在PyQt5中编写一个自定义TableModel,它继承了QtCore.QAbstractTableModel。我希望我的表中有一列只有复选框,没有文本,每行有一列带有按钮 我试图在Qt.Display角色的数据方法中返回QPushButton对象,但显然这是不可能的 所以我的问题是:我能在模型本身中实现它为某些单元格返回某些小部件吗?在我看来,这是模型的工作,但我如何实现这一点 我的第二个问题是如何分配插槽,以便从哪一行的哪个按钮知道操作发生?说明: 我可以在模型本身中实现它为某些单元格返

我正在PyQt5中编写一个自定义TableModel,它继承了QtCore.QAbstractTableModel。我希望我的表中有一列只有复选框,没有文本,每行有一列带有按钮

我试图在Qt.Display角色的数据方法中返回QPushButton对象,但显然这是不可能的

所以我的问题是:我能在模型本身中实现它为某些单元格返回某些小部件吗?在我看来,这是模型的工作,但我如何实现这一点

我的第二个问题是如何分配插槽,以便从哪一行的哪个按钮知道操作发生?

说明: 我可以在模型本身中实现它为某些单元格返回某些小部件吗?在我看来,这是模型的工作,但我如何实现这一点

可能是模型提供了小部件,但它并不常见。通常,模型提供将通过委托显示的信息,并且是可以提供小部件的委托。还可以使用setIndexWidget方法在模型的未链接视图上设置小部件

考虑到第一种情况,解决方案是实现一个委托

如何分配插槽,以便从哪一行的哪个按钮知道操作发生

通常,作为编辑器使用的小部件必须更新模型,然后模型可以通过dataChanged信号通知其他元素,例如,如果用户编写了文本或更改了复选框的状态,但是在单击的情况下,不会通知永久更改,而是临时更改。考虑到这一点,学员可以发出信号

解决方案: 说明: 我可以在模型本身中实现它为某些单元格返回某些小部件吗?在我看来,这是模型的工作,但我如何实现这一点

可能是模型提供了小部件,但它并不常见。通常,模型提供将通过委托显示的信息,并且是可以提供小部件的委托。还可以使用setIndexWidget方法在模型的未链接视图上设置小部件

考虑到第一种情况,解决方案是实现一个委托

如何分配插槽,以便从哪一行的哪个按钮知道操作发生

通常,作为编辑器使用的小部件必须更新模型,然后模型可以通过dataChanged信号通知其他元素,例如,如果用户编写了文本或更改了复选框的状态,但是在单击的情况下,不会通知永久更改,而是临时更改。考虑到这一点,学员可以发出信号

解决方案:
非常感谢,这非常有帮助,我想我现在明白了如何使用代表。我已经将这个解决方案应用到另一个专栏,在那里我想要QdoubleSpinbox。但是,当表格打开时,所有表格的内容都被选为蓝色。你有没有建议我如何避免这种情况?我已经尝试了doubleSpinBox.clearFocus和doubleSpinBox.lineEdit.deselect,但是没有帮助。非常感谢,这非常有帮助,我想我现在了解了如何使用代理。我已经将这个解决方案应用到另一个专栏,在那里我想要QdoubleSpinbox。但是,当表格打开时,所有表格的内容都被选为蓝色。你有没有建议我如何避免这种情况?我已经尝试了doubleSpinBox.clearFocus和doubleSpinBox.lineEdit.deselect,但没有帮助。
from PyQt5 import QtCore, QtGui, QtWidgets


class PushButtonDelegate(QtWidgets.QStyledItemDelegate):
    clicked = QtCore.pyqtSignal(QtCore.QModelIndex)

    def paint(self, painter, option, index):
        if (
            isinstance(self.parent(), QtWidgets.QAbstractItemView)
            and self.parent().model() is index.model()
        ):
            self.parent().openPersistentEditor(index)

    def createEditor(self, parent, option, index):
        button = QtWidgets.QPushButton(parent)
        button.clicked.connect(lambda *args, ix=index: self.clicked.emit(ix))
        return button

    def setEditorData(self, editor, index):
        editor.setText(index.data(QtCore.Qt.DisplayRole))

    def setModelData(self, editor, model, index):
        pass


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    w = QtWidgets.QTableView()
    model = QtGui.QStandardItemModel(0, 2)
    for i in range(10):
        it1 = QtGui.QStandardItem()
        it1.setData(QtCore.Qt.Checked, QtCore.Qt.CheckStateRole)
        it1.setFlags(it1.flags() | QtCore.Qt.ItemIsUserCheckable)
        it2 = QtGui.QStandardItem()
        it2.setData("text-{}".format(i), QtCore.Qt.DisplayRole)
        model.appendRow([it1, it2])

    # pass the view as parent
    delegate = PushButtonDelegate(w)
    w.setItemDelegateForColumn(1, delegate)

    def on_clicked(index):
        print(index.data())

    delegate.clicked.connect(on_clicked)

    w.setModel(model)
    w.show()
    sys.exit(app.exec_())