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