QStyledItemDelegate: Problem with multi-widgets editor



  • Hello,

    I am trying to use an editor made of two QDoubleSpinBox when subclassing QStyledItemDelegate. I have no problem connecting the delegate and editor to the model but I failed to have my editor to show up in my view. I had no such problem with simpler editor.

    Constructor for the Editor
    @Data_editor::Data_editor( QWidget *parent)
    :QFrame(parent)
    {
    lower_bound_spin_ = new QDoubleSpinBox(this);
    upper_bound_spin_ = new QDoubleSpinBox(this);

    QHBoxLayout* layout = new QHBoxLayout(this);
    layout->addWidget(new QLabel("Lower", this));
    layout->addWidget(lower_bound_spin_);
    layout->addStretch();
    layout->addWidget(new QLabel("Upper", this));
    layout->addWidget(upper_bound_spin_);

    this->setLayout(layout);

    this->setFocusPolicy( Qt::StrongFocus );
    }@

    Implementation of the delegate
    @
    QWidget *Data_delegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &option,
    const QModelIndex &index) const

    {
    Data_editor* editor = new Data_editor( parent);

    return editor;

    }

    void Data_delegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
    const QModelIndex &index) const
    {
    QStyledItemDelegate::paint(painter, option, index);
    }

    QSize Data_delegate::sizeHint(const QStyleOptionViewItem &option,
    const QModelIndex &index) const
    {
    return QStyledItemDelegate::sizeHint(option, index);

    }

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

    I played a bit with eventFilter and try to record the log of the events passing through
    @
    bool Data_delegate::eventFilter(QObject *object, QEvent *event)
    {
    Data_editor editor = qobject_cast<Data_editor>(object);
    if (!editor)
    return false;

    QWidget *w_focused = QApplication::focusWidget();
    QEvent::Type t = event->type();
    
    std::string class_name = (w_focused!=0)?w_focused->metaObject()->className():std::string("000");
    ostream_<<class_name <<" "<< QString("%1").arg(t).toStdString()+"\n";
    
    if (event->type() == QEvent::KeyPress) {
        switch (static_cast<QKeyEvent *>(event)->key()) {
        case Qt::Key_Tab:
            emit commitData(editor);
            emit closeEditor(editor, QAbstractItemDelegate::EditNextItem);
            return true;
        case Qt::Key_Backtab:
            emit commitData(editor);
            emit closeEditor(editor, QAbstractItemDelegate::EditPreviousItem);
            return true;
        case Qt::Key_Enter:
        case Qt::Key_Return:
    
            QMetaObject::invokeMethod(this, "_q_commitDataAndCloseEditor",
                                      Qt::QueuedConnection, Q_ARG(QWidget*, editor));
            return false;
        case Qt::Key_Escape:
            // don't commit data
            emit closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
            break;
        default:
            return false;
        }
        if (editor->parentWidget())
            editor->parentWidget()->setFocus();
        return true;
    } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
        //the Hide event will take care of he editors that are in fact complete dialogs
        //if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) {
        if (!editor->isActiveWindow() || (w_focused != editor)) {
            QWidget *w = w_focused;
            //QWidget *w = QApplication::focusWidget();
            while (w) { // don't worry about focus changes internally in the editor
                if (w == editor)
                    return false;
                w = w->parentWidget();
            }
            emit commitData(editor);
            emit closeEditor(editor, NoHint);
        }
    } else if (event->type() == QEvent::ShortcutOverride) {
        if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Escape) {
            event->accept();
            return true;
        }
    }
    return false;
    

    }@

    Which output (first column widget className, second Qcolumn Event type):
    Data_tree_view 75
    Data_tree_view 70
    Data_tree_view 70
    Data_tree_view 70
    Data_tree_view 70
    Data_tree_view 69
    Data_tree_view 69
    Data_tree_view 69
    Data_tree_view 69
    Data_tree_view 13
    Data_tree_view 14
    Data_tree_view 17
    Data_tree_view 26
    Data_editor 8
    Data_editor 67
    Data_editor 74
    Data_editor 12
    Data_editor 10
    Data_editor 11
    Data_editor 12
    Data_tree_view 9

    The editor is painted (event 12) but is never shown. The last event (which probably occurred when I moved the cursor) is the FocusOut event which commit the data and close the editor.

    So what is missing in my delegate/editor such the editor will be shown in my view? Online comments seem to point out to a focus issue but I cannot get it right.

    Thanks


Log in to reply
 

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