无法使用自定义ItemDelegate工作

时间:2010-09-28 10:39:30

标签: python qt qt4 pyqt pyqt4

首先,我是python和pyqt的新手,所以请耐心等待。

我使用带有QSqlTableModel的QTableView,一切都按预期工作。 视图的最后一列只包含0和1作为值,我想显示为复选框,此列应该是可编辑的。

我已经读到你应该继承QItemDelegate,我做了。不幸的是,我的表格不会将最后一列显示为复选框。

我尝试使用setItemDelegateForColumn()仅为最后一列(我喜欢的方式)设置委托,它没有用。所以我修改了它,并使用setItemDelegate()仅对最后一列的请求做出反应,为整个QTableView设置它。它仍然无法工作。不工作意味着没有错误消息它不会做我说的;)似乎我重新实现的方法都没有被调用,除了 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)

有关该问题的任何提示吗?

此外,我对QTableViews selectionModel的currentChanged()信号有困难。我打印选择的右上角坐标。使用鼠标左键单击时,我一直收到错误的索引(无效)。使用光标键可以获得正确的索引。使用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在调用submitAll()时不会抛出错误(返回false),但也不会保存数据。它可以选择OnFieldChange作为editStrategy。哪个我可以忍受,但不是我打算做的。

感谢您的时间。

2 个答案:

答案 0 :(得分:1)

我认为基于QSqlTableModel创建自己的模型会更简单,并且对于QDisplayRole,您的0/1列返回QVariant()并根据值返回Qt :: Checked / Qt :: Unchecked for 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

答案 1 :(得分:0)

至少我设法让我的委托在显示和编辑模式下显示具有正确状态的复选框。因为我无法找到关于如何分享它的完整描述。也许其他人试图在没有使用过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
相关问题