Editor for QAbstractTableModel closes prematurely



  • I've been trying to create my own custom editor widget based on the StarDelegate example. For some reason, the view kills the editor as soon as I click on it, giving it no opportunity to return the data via the delegate. I cannot seem to track down the cause of this.

    My modification of StarDelegate is as follows: the underlying data structure is a vector of ints that for now function as bools indicating whether a particular star is on or off. When you double click on the cell, the editor widget gets created. When you click on one of the stars, the underlying data is modified correctly (the correct star's value is toggled), but before update() or emit editingFinished() have any effect, the QTableView hits it with closeEditor(). So, commitAndCloseEditor() is never triggered.

    I have had to derive the QTableEditor class and promote to it to track this down, but even now I'm stumped. Where in the documentation can I find a list of things that trigger closeEditor()? To eliminate further dead ends: selectionChanged() is not triggered, the only editorEvent()s that get called are mouse presses and releases. I'm not even sure where else to look for a problem. Can anyone help?


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    can you show the modification you made to the delegate ?



  • Thank you very much for the welcome :)
    Ok, here it is. I have removed the cases for the other columns that are not pertinent to this particular editor. I have logged it's actions to determine that it initializes the editor and trasfers the data to it correctly, and also that it calls the appropriate sizeHint. Maybe it's something about the casts? Let me know if I should post code from the other classes.

    @
    QWidget *SpectrumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    if (index.row() < (index.model()->rowCount() - 1)) {
    if (index.data().canConvert<QpxPattern>()) {
    QpxPatternEditor *editor = new QpxPatternEditor(parent);
    connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor()));
    editor->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    return editor;
    } else if ...
    }
    }

    void SpectrumDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    {
    if (index.row() < (index.model()->rowCount() - 1)) {
    if (index.data().canConvert<QpxPattern>()) {
    QpxPattern qpxPattern = qvariant_cast<QpxPattern>(index.data());
    QpxPatternEditor *qpxPatternEditor = qobject_cast<QpxPatternEditor *>(editor);
    qpxPatternEditor->setQpxPattern(qpxPattern);
    } else if ...
    }
    }

    void SpectrumDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    {
    if (index.row() < (index.model()->rowCount() - 1)) {
    if (index.data().canConvert<QpxPattern>()) {
    QpxPatternEditor *qpxPatternEditor = qobject_cast<QpxPatternEditor *>(editor);
    model->setData(index, QVariant::fromValue(qpxPatternEditor->qpxPattern()), Qt::EditRole);
    } else if ...
    }
    }

    void SpectrumDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    if (index.row() < (index.model()->rowCount() - 1)) {
    if (index.data().canConvert<QpxPattern>()) {
    QpxPattern qpxPattern = qvariant_cast<QpxPattern>(index.data());

            if (option.state & QStyle::State_Selected)
                painter->fillRect(option.rect, option.palette.highlight());
    
            qpxPattern.paint(painter, option.rect, option.palette,
                             QpxPattern::ReadOnly);
        } else if ...
    }
    

    }

    void SpectrumDelegate::updateEditorGeometry(QWidget *editor,
    const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    editor->setGeometry(option.rect);
    }

    void SpectrumDelegate::commitAndCloseEditor()
    {
    QpxPatternEditor editor = qobject_cast<QpxPatternEditor>(sender());
    QpxPattern qp = editor->qpxPattern();
    QVector<int> iv = qp.pattern();
    emit commitData(editor);
    emit closeEditor(editor);
    }

    QSize SpectrumDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    if (index.data().canConvert<QpxPattern>()) {
    QpxPattern qpxPattern = qvariant_cast<QpxPattern>(index.data());
    return qpxPattern.sizeHint();
    } else {
    return QStyledItemDelegate::sizeHint(option, index);
    }
    }@


  • Lifetime Qt Champion

    What kind of widget is your QpxPatternEditor ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.