Не могу получить пользовательский ItemDelegate для работы - PullRequest
0 голосов
/ 28 сентября 2010

Во-первых, я новичок в python и pyqt, поэтому, пожалуйста, потерпите меня.

Я использую QTableView с QSqlTableModel, все работает как задумано. Последний столбец представления содержит только 0 и 1 в качестве значения, которое я хочу отобразить как флажок, и этот столбец должен быть редактируемым.

Я прочитал, что вы должны создать подкласс QItemDelegate, что я и сделал. К сожалению, моя таблица не будет отображать последний столбец как флажок.

Я пытался установить делегат только для последнего столбца (так, как я бы предпочел), используя setItemDelegateForColumn (), он не работал. Поэтому я изменил его и установил для всего QTableView, используя setItemDelegate (), реагируя только на запросы к последнему столбцу. Это все еще не будет работать. «Не работать» означает, что сообщений об ошибках нет, просто он не будет делать то, что я говорю;) Кажется, что ни один из методов, которые я переопределил, никогда не вызывается, кроме init (). Так что я предполагаю, что я упускаю что-то фундаментальное.

Я извлек соответствующие строки кода, KSCheckBoxDelegate - мой подкласс. Это версия, в которой делегат настроен для всего QTableView.


-- code from applications main class --
self.taglist = QTableView()
self.tagmodel = QSqlTableModel()
self.tagmodel.setTable("data")
self.tagmodel.select()
self.taglist.setModel(self.tagmodel)
print self.taglist.itemDelegate()
myDel = KSCheckBoxDelegate(self)
myDel.colnumber = 3
self.taglist.setItemDelegate(myDel)


-- KSCheckBoxDelegate.py --
from PyQt4.QtGui import *

class KSCheckBoxDelegate(QStyledItemDelegate):

    colnumber = None

    def __init__ (self, parent = None):
        print "KSCheckBoxDelegate::init"
        QStyledItemDelegate.__init__(self, parent)

    def createEditor(self, parent, option, index):
        print "KSCheckBoxDelegate::createEditor"
        if index.column()==self.colnumber:
            return QCheckBox(self)
        else:
            return QStyledItemDelegate.createEditor(self, parent, option, index)

    def setEditorData (self, editor, index):
        print "KSCheckBoxDelegate::setEditorData"
        if index.column() == self.colnumber:
            cont = index.model().data(index, Qt.DisplayRole).toString()
            if cont == "1":
                editor.setCheckState(Qt.Checked)
            else:
                editor.setCheckState(Qt.UnChecked)
        else:
            QStyledItemDelegate.setEditorData(self,editor, index)

    def setModelData (self, editor, model, index):
        print "KSCheckBoxDelegate::setModelData"
        if index.column() == self.colnumber:
            if editor.checkBox.checkState() == Qt.Checked:
                model.setData(index, 1)
            else:
                model.setData(index, 0)
        else:
            QStyledItemDelegate.setModelData(self, editor, model, index)

Есть какие-нибудь подсказки для меня по этому вопросу?

Кроме того, у меня возникают трудности с сигналом currentChanged () в модели выбора QTableViews. Я печатаю верхние правые координаты выделения. Я продолжаю получать неправильные индексы (не недействительные) при нажатии левой кнопкой мыши. Использование клавиш курсора дает мне правильные индексы. Использование selectionChanged () имеет такое же поведение. Я на самом деле получаю координаты второй последней выбранной ячейки QTableView. Например, я нажимаю на координаты <1,1> <2,1>, второй щелчок покажет мне координаты <1,1>.


selInd = self.taglist.selectionModel().selectedIndexes()
if(len(selInd) > 0):
    self.xPosData=selInd[0].column()
    self.yPosData=selInd[0].row()

Исправлено самостоятельно, с использованием QTableView.currentIndex () вместо selectionModel.selectedIndexes () :)

И, наконец, использование OnManualSubmit в качестве editStrategy не выдает ошибку (возвращает false) при вызове submitAll (), но также не сохраняет данные. Это работает с выбором OnFieldChange как editStrategy. С чем я могу жить, но я не собирался этого делать.

Спасибо за ваше время.

Хорст

Ответы [ 2 ]

1 голос
/ 29 сентября 2010

Я думаю, что было бы проще создать свою собственную модель на основе QSqlTableModel, и для вашего столбца 0/1 вернуть QVariant () для QDisplayRole и вернуть Qt :: Checked / Qt :: Unchecked для Qt :: CheckStateRole в зависимости от значения. Для всех остальных случаев вернуть QSqlTableModel :: data

class MySqlTableModel: public QSqlTableModel
{
public:
// contructors
    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole)
    {
        if(index.column() == 3 /* your 0/1 column */)
        {
            if(role == Qt::DisplayRole)
            {
                return QVariant();
            }
            else if(role == Qt::CheckStateRole)
            {
                QString value = QSqlTableModel::data(index, Qt::DisplayRole).toString();
                return value == "1" ? Qt::Checked : Qt::Unchecked;
            }
        }

        return QSqlTableModel::data(index, role);
    }
};

Я знаю, что это код C ++, но логика все та же, поэтому просто перенастройте его для Python

0 голосов
/ 30 сентября 2010

по крайней мере мне удалось сделать так, чтобы мои делегаты показывали флажки с правильным состоянием в режиме отображения и редактирования. Потому что я не мог найти полное описание того, как это сделать, и поделиться им. Может быть, другие люди пытаются сделать нечто подобное, не работая с qt когда-либо раньше.

Отсутствует только одна вещь, это элементы, которые можно редактировать, я думаю, это связано с вопросом о флагах, который я задал в своем первом сообщении.

- KSCheckBoxDelegate.py -


class KSCheckBoxDelegate(QStyledItemDelegate):
    def __init__ (self, parent = None):
        print "KSCheckBoxDelegate::init"
        QStyledItemDelegate.__init__(self, parent)

    def createEditor(self, parent, option, index):
        print "KSCheckBoxDelegate::createEditor"
        return QCheckBox(parent)

    def setEditorData (self, editor, index):
        print "KSCheckBoxDelegate::setEditorData"
        cont = index.model().data(index, Qt.DisplayRole).toString()
        if cont == "1":
            editor.setCheckState(Qt.Checked)
        else:
            editor.setCheckState(Qt.Unchecked)

    def setModelData (self, editor, model, index):
        print "KSCheckBoxDelegate::setModelData"
        if editor.checkState() == Qt.Checked:
            model.setData(index, 1)
        else:
            model.setData(index, 0)

    def paint (self, painter, option, index):
        myopt = QStyleOptionViewItemV4(option)
        newopt = QStyleOptionButton()
        newopt.rect = myopt.rect
        newopt.palette = myopt.palette
        if index.data().toBool():
            newopt.state |= QStyle.State_On
        QApplication.style().drawControl(QStyle.CE_CheckBox, newopt, painter)

    def sizeHint (self, option, index):
        return 18
...