python - Qt 模型/ View 表中的按钮

标签 python pyqt pyqt5 qtableview qabstracttablemodel

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

我尝试在 data 方法中为 Qt.Display 角色返回一个 QPushButton 对象,但显然这是不可能的。

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

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

最佳答案

说明:

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

模型可能提供了小部件,但并不常见。一般来说,模型提供的信息将通过委托(delegate)来显示,并且是可以提供小部件的委托(delegate)。还可以使用 setIndexWidget 方法在模型的未链接 View 上设置小部件。

考虑第一种情况,解决方案是实现委托(delegate)。

我如何分配插槽以便我知道操作是从哪个按钮(从哪一行)发生的?

一般来说,小部件用作编辑器,因此您必须更新模型,然后模型可以通过 dataChanged 信号通知其他元素,例如用户写入文本或更改复选框的状态,但在单击的情况不会通知永久更改,而是暂时的。考虑到这一点,代表可以发出信号。

解决方案:

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_())

关于python - Qt 模型/ View 表中的按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58649520/

相关文章:

python - Python 2.7 的 Qt5 和 QtQuick 2 绑定(bind)

python - 使用 PyQt5 运行命令并获取 stdout 和 stderr

python-3.x - 如何在 Python 3.5、PyQt5 中调整 QMessageBox 的大小

python - QLineEdit PyQT5 输入上的火柴盒键盘

python - 尝试安装 python 数据表时出现 C++ 编译器错误

python - Django 标记迁移到 GAE

python - 禁用 qslider 的特定键盘事件

python - Pandas 中的索引错误

python - 如何让QTableView在再次加载数据后刷新背景颜色

python - pyqtgraph - 是否有可能没有直方图的 ImageView?