Кнопка в Qt Model / View Table - PullRequest
       10

Кнопка в Qt Model / View Table

1 голос
/ 31 октября 2019

Я пишу пользовательскую TableModel в PyQt5, наследуя от QtCore.QAbstractTableModel. Я хочу, чтобы в моей таблице был только один столбец с флажками, без текста и один столбец с кнопкой в ​​каждой строке.

Я пытался вернуть объект QPushButton в методе data для роли Qt.Display, но, по-видимому, это невозможно.

Поэтому мой вопрос: могу ли я реализовать вСама модель, чтобы она возвращала определенные виджеты для определенных ячеек? На мой взгляд, это работа модели, но как мне этого добиться?

Мой второй вопрос - как мне назначить слоты, чтобы я знал, из какой кнопки (из какой строки)) действие произошло?

1 Ответ

2 голосов
/ 31 октября 2019

Объяснение:

Можно ли реализовать в самой модели, чтобы она возвращала определенные виджеты для определенных ячеек? На мой взгляд, это работа модели, но как мне этого добиться?

Может быть, модель предоставляет виджеты, но это не распространено. В общем, модель предоставляет информацию, которая будет отображаться через делегата, и является делегатом, который может предоставлять виджеты. Существует также альтернатива установки виджетов в несвязанном представлении модели с использованием метода setIndexWidget.

В первом случае решение заключается в реализации делегата.

как янужно назначить слоты, чтобы я знал, с какой из кнопок (из какой строки) произошло действие?

В общем случае виджеты, которые используются в качестве редакторов, поэтому необходимо обновить модель, а затемМодель может уведомлять другие элементы с помощью сигнала 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_())
...