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. QTreeView with QItemDelegate and QComboBox inside not work propertly

QTreeView with QItemDelegate and QComboBox inside not work propertly

Scheduled Pinned Locked Moved General and Desktop
5 Posts 2 Posters 4.8k 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.
  • scastielloS Offline
    scastielloS Offline
    scastiello
    wrote on last edited by
    #1

    Hi guys,

    I have a problem with the QItemDelegate because my QTreeView need to click over the QComboBox cell one time for enter in edit mode and other time to expand the QComboBox. I need that this firts click expand the QComboBox.

    I try with the edit trigers of the QTreeView but it work similar, I need that when click one first time enter in edit mode.

    It is posible to enter in edit modo when mouse over the cell with combobox and them the first click expand the QComboBox?

    I have already try with comboBox->showPopup(); in the setEditorData of QItemDelegate but it not work fine.

    Please can anyone help me?

    1 Reply Last reply
    0
    • T Offline
      T Offline
      tgru
      wrote on last edited by
      #2

      For me it is working with showPopup(). Difficult to guess whats wrong in your situation. Do you have some minimal code?

      1 Reply Last reply
      0
      • scastielloS Offline
        scastielloS Offline
        scastiello
        wrote on last edited by
        #3

        Hi, i will try to explain my situation. I have a QTreeView.

        @
        m_table = new QTreeView(this);
        m_table->setEditTriggers(QAbstractItemView::AllEditTriggers);
        m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
        m_table->setSelectionMode(QAbstractItemView::SingleSelection);
        m_table->setDragEnabled(false);
        m_table->setAllColumnsShowFocus(true);
        m_table->setAlternatingRowColors(false);
        m_table->setRootIsDecorated(false);
        m_table->setItemsExpandable(false);
        m_table->setSortingEnabled(false);
        m_table->header()->setClickable(false);
        m_table->header()->setStretchLastSection(false);
        m_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

        m_model = new MyItemModel(m_table);
        m_table->setModel(m_model);

        m_selectionModel = new QItemSelectionModel(m_model);
        m_table->setSelectionModel(m_selectionModel);

        m_delegate = new MyDelegate(
        m_table);

        m_table->header()->setResizeMode(0, QHeaderView::Stretch);
        m_table->header()->resizeSection(1, 135);
        m_table->header()->resizeSection(2, 135);
        m_table->header()->resizeSection(3, 60);

        m_table->setItemDelegateForColumn(1, m_delegate);
        m_table->setItemDelegateForColumn(2, m_delegate);
        m_table->setItemDelegateForColumn(3, m_delegate);
        @

        The delegate is responsible for managing the drop-down is as follows.

        @
        void MyItemDelegate::paint(QPainter *painter,
        const QStyleOptionViewItem &option, const QModelIndex &index) const
        {
        if ((index.column() == 1) || (index.column() == 2))
        {
        QStyleOptionComboBox comboBoxOption;
        comboBoxOption.rect = option.rect;
        comboBoxOption.state = QStyle::State_Active; // | QStyle::State_Enabled;
        comboBoxOption.currentText = index.model()->data(index).toString();
        QApplication::style()->drawComplexControl(QStyle::CC_ComboBox,
        &comboBoxOption, painter);
        QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel,
        &comboBoxOption, painter);
        }
        else if (index.column() == 3)
        {
        QStyleOptionButton buttonOption;
        buttonOption.rect = option.rect;
        buttonOption.state = QStyle::State_Active; // | QStyle::State_Enabled;
        buttonOption.text = index.model()->data(index).toString();
        QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption,
        painter);
        }
        else
        {
        QItemDelegate::paint(painter, option, index);
        }

        }

        QWidget* MyItemDelegate::createEditor(QWidget parent,
        const QStyleOptionViewItem &option, const QModelIndex &index) const
        {
        if ((index.column() == 1) || (index.column() == 2))
        {
        QComboBox
        comboStatus = new QComboBox(parent);

            return comboStatus;
        }
        else if (index.column() == 3)
        {
            QPushButton* pushButton = new QPushButton(
                    index.model()->data(index).toString(), parent);
        
            connect(pushButton, SIGNAL(clicked()), this, SLOT(wasDeleteClicked()));
        
            return pushButton;
        }
        else
        {
            return QItemDelegate::createEditor(parent, option, index);
        }
        

        }

        void MyItemDelegate::setEditorData(QWidget editor,
        const QModelIndex &index) const
        {
        if ((index.column() == 1) || (index.column() == 2))
        {
        QVariant value = index.model()->data(index);
        QComboBox
        comboBox = static_cast<QComboBox*>(editor);
        comboBox->setCurrentIndex(comboBox->findText(value.toString()));
        //comboBox->showPopup();
        }
        else if ((index.column() == 3))
        {
        //QPushButton* pushButton = static_cast<QPushButton*>(editor);
        //pushButton->click();
        }
        else
        {
        QItemDelegate::setEditorData(editor, index);
        }
        }

        void MyItemDelegate::setModelData(QWidget editor,
        QAbstractItemModel model, const QModelIndex &index) const
        {
        if ((index.column() == 1) || (index.column() == 2))
        {
        QComboBox
        comboBox = static_cast<QComboBox
        >(editor);
        QVariant value = comboBox->currentIndex();
        model->setData(index, value);
        }
        else if ((index.column() == 3))
        {

        }
        else
        {
            QItemDelegate::setModelData(editor, model, index);
        }
        

        }
        @

        In MyItemDelegate::setEditorData if I uncomment the showPopup the dropdow view is visible for a moment (a second) and then it close.

        Thanks for your answer, a greeting.

        1 Reply Last reply
        0
        • T Offline
          T Offline
          tgru
          wrote on last edited by
          #4

          The following FULL example works for me (popup not disappearing).
          Please compile and check. I removed the selection model and changed MyDelegate to MyItemDelegate.

          Demo.h

          @
          #include <QMainWindow>
          #include <QItemDelegate>

          class MyItemDelegate: public QItemDelegate {
          Q_OBJECT
          public:
          MyItemDelegate(QObject *parent = 0):QItemDelegate(parent){};
          void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
          QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
          void setEditorData(QWidget *editor, const QModelIndex &index) const;
          void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
          };

          class CTableModel: public QAbstractTableModel {
          Q_OBJECT
          public:
          CTableModel (QObject *parent=0): QAbstractTableModel(parent) {}
          int rowCount(const QModelIndex &parent) const;
          int columnCount(const QModelIndex &) const;
          QVariant data(const QModelIndex &index, int role) const;
          Qt::ItemFlags flags(const QModelIndex &index) const;
          bool setData(const QModelIndex &index, const QVariant &value, int role);
          };
          @

          Demo.cpp

          @
          #include <QApplication>
          #include <QPushButton>
          #include <QTreeView>
          #include <QComboBox>
          #include <QHeaderView>
          #include "Demo.h"

          int main(int argc, char **argv) {
          QApplication App(argc,argv);
          QTreeView *m_table = new QTreeView;
          m_table->setEditTriggers(QAbstractItemView::AllEditTriggers);
          m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
          m_table->setSelectionMode(QAbstractItemView::SingleSelection);
          m_table->setDragEnabled(false);
          m_table->setAllColumnsShowFocus(true);
          m_table->setAlternatingRowColors(false);
          m_table->setRootIsDecorated(false);
          m_table->setItemsExpandable(false);
          m_table->setSortingEnabled(false);
          m_table->header()->setClickable(false);
          m_table->header()->setStretchLastSection(false);
          m_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

          CTableModel *m_model = new CTableModel;
          m_table->setModel(m_model);

          MyItemDelegate* m_delegate = new MyItemDelegate;

          m_table->setItemDelegateForColumn(1, m_delegate);
          m_table->setItemDelegateForColumn(2, m_delegate);
          m_table->setItemDelegateForColumn(3, m_delegate);
          m_table->show();
          return App.exec();
          }

          void MyItemDelegate::paint(QPainter *painter,
          const QStyleOptionViewItem &option, const QModelIndex &index) const
          {
          if ((index.column() == 1) || (index.column() == 2))
          {
          QStyleOptionComboBox comboBoxOption;
          comboBoxOption.rect = option.rect;
          comboBoxOption.state = QStyle::State_Active; // | QStyle::State_Enabled;
          comboBoxOption.currentText = index.model()->data(index).toString();
          QApplication::style()->drawComplexControl(QStyle::CC_ComboBox,
          &comboBoxOption, painter);
          QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel,
          &comboBoxOption, painter);
          }
          else
          {
          QItemDelegate::paint(painter, option, index);
          }

          }

          QWidget* MyItemDelegate::createEditor(QWidget parent,
          const QStyleOptionViewItem &option, const QModelIndex &index) const
          {
          if ((index.column() == 1) || (index.column() == 2))
          {
          QComboBox
          comboStatus = new QComboBox(parent);
          comboStatus->addItem("i1");
          comboStatus->addItem("i2");
          comboStatus->addItem("i3");
          comboStatus->addItem("i4");
          return comboStatus;
          }
          else
          {
          return QItemDelegate::createEditor(parent, option, index);
          }
          }

          void MyItemDelegate::setEditorData(QWidget editor,
          const QModelIndex &index) const
          {
          if ((index.column() == 1) || (index.column() == 2))
          {
          QVariant value = index.model()->data(index);
          QComboBox
          comboBox = static_cast<QComboBox*>(editor);
          comboBox->setCurrentIndex(2);
          comboBox->showPopup();
          }
          else
          {
          QItemDelegate::setEditorData(editor, index);
          }
          }

          void MyItemDelegate::setModelData(QWidget editor,
          QAbstractItemModel model, const QModelIndex &index) const
          {
          if ((index.column() == 1) || (index.column() == 2))
          {
          QComboBox
          comboBox = static_cast<QComboBox
          >(editor);
          QVariant value = comboBox->currentIndex();
          model->setData(index, value);
          }
          else
          {
          QItemDelegate::setModelData(editor, model, index);
          }
          }
          int CTableModel::rowCount(const QModelIndex &) const {
          return 10;
          }
          int CTableModel::columnCount(const QModelIndex &) const {
          return 5;
          }

          QVariant CTableModel::data(const QModelIndex &index, int role) const {
          if (role == Qt::DisplayRole)
          return index.row()+index.column();
          return QVariant();
          }
          Qt::ItemFlags CTableModel::flags(const QModelIndex &) const {
          return Qt::ItemIsEnabled | Qt::ItemIsEditable;
          }
          bool CTableModel::setData(const QModelIndex &, const QVariant &, int ) {return true;}
          @

          1 Reply Last reply
          0
          • scastielloS Offline
            scastielloS Offline
            scastiello
            wrote on last edited by
            #5

            Hi,

            I tryed with your example on Windows platform with the last Qt version and it work perfectly, but my example on Linux platform with Qt 4.8.5 version the showPopup() not work propertly.

            I will try an other logic solution to be usable for the user with 2 click to show comboBox.

            Thanks you very much.

            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