Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QStyledItemDelegate painting problem with QComboBox
Forum Updated to NodeBB v4.3 + New Features

QStyledItemDelegate painting problem with QComboBox

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 3.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • gde23G Offline
    gde23G Offline
    gde23
    wrote on last edited by
    #1

    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);
    }
    
    raven-worxR VRoninV 2 Replies Last reply
    0
    • gde23G gde23

      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);
      }
      
      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

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

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      1
      • gde23G Offline
        gde23G Offline
        gde23
        wrote on last edited by
        #3

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

        raven-worxR 1 Reply Last reply
        0
        • gde23G gde23

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

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          @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);
          }
          

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          3
          • gde23G gde23

            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);
            }
            
            VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by
            #5

            @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

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            1 Reply Last reply
            2
            • gde23G Offline
              gde23G Offline
              gde23
              wrote on last edited by
              #6

              @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..

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved