QStyledItemDelegate painting problem with QComboBox



  • Hello,

    i have a QTreeView with a delegate inheriting from QStyledItemDelegate to display a QComboBox.
    When the QTreeView is "just displayed" everything renders fine.
    However when i click an entry of the QTreeView to edit it, the content of the cell is painted over twice, once with the text that would display normally when not editing and once the QComboBox is painted which looks like this:

    alt text
    Below is my code. What am i missing?
    Another thing, that would be nice is that the QComboBox instantaneously pops up the item list. When clicked for editing. At the moment there is one doubleclcik needed to enter the edit mode (with the rendering problem) and another click to popUp the list.

    #include "delegate.h"
    
    #include <QApplication>
    #include <QComboBox>
    
    Delegate::Delegate(QObject *parent)
        : QStyledItemDelegate(parent){}
    
    QWidget *Delegate::createEditor(QWidget *parent,
        const QStyleOptionViewItem &/* option */,
        const QModelIndex &index ) const
    {   
        QStringList entries = index.model()->data(index, 1340).toStringList();
        QComboBox *editor = new QComboBox(parent);
        for(int i = 0; i < entries.size(); i++)
        {
            editor->addItem(entries.at(i));
        }
        editor->setFrame(false);
        return editor;
    }
    
    void Delegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    {    
        int value = index.model()->data(index, Qt::EditRole).toUInt();
        QComboBox *comboBox = static_cast<QComboBox*>(editor);
        comboBox->setCurrentIndex(value);
    }
    
    void Delegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    {
        QComboBox *comboBox = static_cast<QComboBox*>(editor);            
        QString value = comboBox->itemText(comboBox->currentIndex());
        model->setData(index, value, Qt::EditRole);
        model->setData(index, comboBox->currentIndex(), Qt::EditRole);
    }
    
    void Delegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
    {
        editor->setGeometry(option.rect);
    }
    
    
    void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {    
        QStyleOptionViewItemV4 myOption = option;
        QString text = index.model()->data(index, Qt::DisplayRole).toString();
        myOption.text = text;
    
        QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &myOption, painter);
    }
    

  • Moderators

    @gde23
    are you using stylesheets in your application?
    It looks like some style declarations also remove the background from the combobox editor widget.



  • no there are no style-sheets. This is my default desktop look (KDE with Breeze Dark)


  • Moderators

    @gde23
    You can still try to set a background on the combobox editor:

    QWidget *Delegate::createEditor(QWidget *parent,
        const QStyleOptionViewItem &/* option */,
        const QModelIndex &index ) const
    {   
        QStringList entries = index.model()->data(index, 1340).toStringList();
        QComboBox *editor = new QComboBox(parent);
        for(int i = 0; i < entries.size(); i++)
        {
            editor->addItem(entries.at(i));
        }
        editor->setFrame(false); //MAYBE THIS CAUSES THAT THE COMBOBOX HAS ALSO NO BACKGROUND
        editor->setStylesheet("QComboBox { background: white; border: 1px solid darkGrey; }");
    
        return editor;
    }
    

    Alternatively you can try the following (untested):

    void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {    
        QStyleOptionViewItemV4 myOption = option;
        if( !(option.state | QStyle::State_Editing) { // not sure if the state indicates if an item is open for editing?
            QString text = index.model()->data(index, Qt::DisplayRole).toString();
            myOption.text = text;
        }
        else
             myOption.text = QString();
        QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &myOption, painter);
    }
    


  • @gde23 said in QStyledItemDelegate painting problem with QComboBox:

    model->setData(index, value, Qt::EditRole);
    model->setData(index, comboBox->currentIndex(), Qt::EditRole);

    You are overwriting data

    Your paint() is wrong just remove it, the default works



  • @raven-worx
    removing editor->setFrame(false); did the trick. Thanks a lot. Setting a stylesheet was not required.
    @VRonin: Thaks as well, those were some leftovers from trying out different things..


Log in to reply
 

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