#combobox #pyqt #qtableview #qitemdelegate
#выпадающий список #pyqt #qtableview #qitemdelegate
Вопрос:
Я использую пользовательский делегат для отображения столбца выпадающих списков в моем QTableView. Значения одинаковы для всех выпадающих списков, так что на самом деле меня беспокоит не общая часть.
Я хочу, чтобы они отображали в качестве выбранного элемента некоторое значение, которое я могу извлечь из базы данных. У меня есть доступ к базе данных от делегата, но для отправки моего запроса мне нужна строка выпадающего списка.
Итак, я предполагаю, что мой вопрос таков: как вы можете выполнить итерацию по всем строкам таблицы и выполнить какое-либо действие внутри пользовательского делегата?
Если это может помочь, вот мой пользовательский класс делегата :
class ComboBoxDelegate(QtGui.QItemDelegate):
def __init__(self, parent, itemslist):
QtGui.QItemDelegate.__init__(self, parent)
self.itemslist = itemslist
self.parent = parent
def paint(self, painter, option, index):
# Get Item Data
value = index.data(QtCore.Qt.DisplayRole).toInt()[0]
# value = self.itemslist[index.data(QtCore.Qt.DisplayRole).toInt()[0]]
# fill style options with item data
style = QtGui.QApplication.style()
opt = QtGui.QStyleOptionComboBox()
opt.currentText = str(self.itemslist[value])
opt.rect = option.rect
# draw item data as ComboBox
style.drawComplexControl(QtGui.QStyle.CC_ComboBox, opt, painter)
self.parent.openPersistentEditor(index)
def createEditor(self, parent, option, index):
##get the "check" value of the row
# for row in range(self.parent.model.rowCount(self.parent)):
# print row
self.editor = QtGui.QComboBox(parent)
self.editor.addItems(self.itemslist)
self.editor.setCurrentIndex(0)
self.editor.installEventFilter(self)
self.connect(self.editor, QtCore.SIGNAL("currentIndexChanged(int)"), self.editorChanged)
return self.editor
# def setEditorData(self, editor, index):
# value = index.data(QtCore.Qt.DisplayRole).toInt()[0]
# editor.setCurrentIndex(value)
def setEditorData(self, editor, index):
text = self.itemslist[index.data(QtCore.Qt.DisplayRole).toInt()[0]]
pos = self.editor.findText(text)
if pos == -1:
pos = 0
self.editor.setCurrentIndex(pos)
def setModelData(self,editor,model,index):
value = self.editor.currentIndex()
model.setData(index, QtCore.QVariant(value))
def updateEditorGeometry(self, editor, option, index):
self.editor.setGeometry(option.rect)
def editorChanged(self, index):
check = self.editor.itemText(index)
id_seq = self.parent.selectedIndexes[0][0]
update.updateCheckSeq(self.parent.db, id_seq, check)
И я вызываю его из QTableView следующим образом :
self.setEditTriggers(QtGui.QAbstractItemView.CurrentChanged)
self.viewport().installEventFilter(self)
self.setItemDelegateForColumn(13,ComboBoxDelegate(self, self.checkValues))
Надеюсь, я был достаточно ясен, спасибо за ваше внимание
Ответ №1:
Не уверен, правильно ли обращаться к базе данных из делегата. Ваш делегат может содержать ссылку на экземпляр QAbstractTableModel, на который ссылается QTableView. Затем вы можете использовать методы в модели для перебора строк таблицы.
Комментарии:
1. Что ж, мне удалось отобразить правильный выбранный элемент в сборных ящиках. Но, как вы заявили, я обращаюсь к базе данных из делегата, но я действительно не вижу, как реализовать то, что вы предложили. И у меня все еще есть проблема: выпадающие списки не «следуют», когда я переупорядочиваю TableView..
2. Возможно ли вызвать перерисовку делегата из модели?
3. но как модель узнает о делегате, хорошо, вы можете передать ссылку делегата на модель. Делегаты предназначены для улучшения представления (т. Е. лучшего просмотра). Взаимозависимость модели и делегата сделала бы ваш код хрупким.
4. Ну, на данный момент у меня нет экземпляра делегата в модели. На самом деле у меня есть экземпляр модели и один из делегатов на viex, поэтому у меня есть «взаимный доступ», но на самом деле они не взаимозависимы. Я пытался обновить делегат практически везде в моем коде, похоже, ничего не работает..