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. "setItemDelegateForColumn" problem.
QtWS25 Last Chance

"setItemDelegateForColumn" problem.

Scheduled Pinned Locked Moved General and Desktop
10 Posts 3 Posters 5.8k Views
  • 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.
  • H Offline
    H Offline
    House15
    wrote on 2 Mar 2015, 16:12 last edited by
    #1

    Hello, everyone.

    Has been studying the of models in Qt 5.4 and encountered a strange behavior of the method "setItemDelegateForColumn". I use QTreeViev performance and QAbstrastitemModel  to implement elements of the tree with delegates of QComboBox.

    Here is code of my delegate:
    @
    #ifndef COMBOBOXDELEGATE_H
    #define COMBOBOXDELEGATE_H
    #include <QItemDelegate>
    #include <QComboBox>

    class ComboBoxDelegate : public QItemDelegate
    {
    public:
    Q_OBJECT
    public:

          ComboBoxDelegate(QObject *parent = 0);
          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;
          void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
          ~ComboBoxDelegate();
    

    };

    #endif // COMBOBOXDELEGATE_H
    @

    And cpp:
    @
    #include "comboboxdelegate.h"

    ComboBoxDelegate::ComboBoxDelegate(QObject *parent): QItemDelegate(parent)
    {
    //createEditor(parent);
    }
    ComboBoxDelegate::~ComboBoxDelegate()
    {

    }

    QWidget *ComboBoxDelegate::createEditor(QWidget parent, const QStyleOptionViewItem &/ option /, const QModelIndex &/ index */) const
    {
    QComboBox *editor = new QComboBox(parent);
    QStringList list ;
    list << "Non" << "WithUpdates" << "WithInners";
    editor->addItems(list);
    return editor;
    }

    void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    {
    QString value = index.model()->data(index, Qt::DisplayRole).toString();
    QComboBox comboBox = static_cast<QComboBox>(editor);
    comboBox->addItem(value);
    }

    void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    {
    QComboBox comboBox = static_cast<QComboBox>(editor);
    QString value = comboBox->currentText();
    model->setData(index, value);
    }

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

    In the process executing code of my program, setting the delegate in column 0:
    @
    Tree::Tree(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Tree)
    {
    ui->setupUi(this);
    treeModel = new TreeModel();
    ...
    comboDelegate = new ComboBoxDelegate(ui->treeView);
    ...
    ui->treeView->setItemDelegateForColumn(0, comboDelegate);
    ui->treeView->setModel(treeModel);
    @

    The problem is that if you set a delegate similarly (which is, I mean, is not correct), the application is going to run, but in the column where there should be a delegate is not what I need.

    However, methods of assembly editor in my delegate already redefined. If I include them in the program code _ and installed editor  using model indexes already added elements, I get my delegate, but only in one line, rather than in the entire column, as we would like:
    @
    Tree::Tree(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Tree)
    {
    ui->setupUi(this);
    treeModel = new TreeModel();

    comboDelegate = new ComboBoxDelegate(ui->treeView);
    comboDelegate->createEditor(ui->treeView,QStyleOptionViewItem(),QModelIndex());
    
    ui->treeView->setItemDelegateForColumn(0, comboDelegate);
    ui->treeView->setModel(treeModel);
    
    QModelIndex index = ui->treeView->currentIndex();
    treeModel->insertRows(0,3,index);
    ...
    

    @

    If I just make out the code as documentation tells me, that the program will abort with an error "Segmentation error".
    @
    Tree::Tree(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Tree)
    {
    ui->setupUi(this);
    treeModel = new TreeModel();
    ui->treeView->setItemDelegateForColumn(0, comboDelegate);
    ui->treeView->setModel(treeModel);
    QModelIndex index = ui->treeView->currentIndex();
    treeModel->insertRows(0,3,index);
    ....
    @

    However, the work of this application fails "Segmentation error." Can you tell me anything prompt?

    Thanks in advance.

    1 Reply Last reply
    0
    • D Offline
      D Offline
      dheerendra
      Qt Champions 2022
      wrote on 2 Mar 2015, 16:43 last edited by
      #2

      I saw only last code snippet. I don't see your delegate object is not created. This may be reason for crash ?

      Dheerendra
      @Community Service
      Certified Qt Specialist
      http://www.pthinks.com

      1 Reply Last reply
      2
      • H Offline
        H Offline
        House15
        wrote on 2 Mar 2015, 19:31 last edited by
        #3

        bI saw only last code snippet. I don’t see your delegate object is not created. This may be reason for crash ?q.

        For crash - maybe. This code is working (ie. Does not fall), but the delegate is not displayed.
        @ Tree::Tree(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::Tree)
        {
        ui->setupUi(this);
        treeModel = new TreeModel();

            comboDelegate = new ComboBoxDelegate(ui->treeView);
            comboDelegate->createEditor(ui->treeView,QStyleOptionViewItem(),QModelIndex());
         
            ui->treeView->setItemDelegateForColumn(0, comboDelegate);
            ui->treeView->setModel(treeModel);
         
            QModelIndex index = ui->treeView->currentIndex();
            treeModel->insertRows(0,3,index);
            ...
        

        @

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on 2 Mar 2015, 20:58 last edited by
          #4

          Hi

          [quote author="House15" date="1425312736"]Hello, everyone.
          @
          Tree::Tree(QWidget *parent) :
          QDialog(parent),
          ui(new Ui::Tree)
          {
          ui->setupUi(this);
          treeModel = new TreeModel();

          ui->treeView->setItemDelegateForColumn(0, comboDelegate); << comboDelegate is used uninitialized
          
          ui->treeView->setModel(treeModel);
          QModelIndex index = ui->treeView->currentIndex();
          treeModel->insertRows(0,3,index);
          

          @
          [/quote]

          You should also first setup your model on your view and then your delegate.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • H Offline
            H Offline
            House15
            wrote on 3 Mar 2015, 07:30 last edited by
            #5

            That'S Perfect. Did as you said, but the result is unsatisfactory: the delegate does not appear on the form.

            @Tree::Tree(QWidget *parent) :
            QDialog(parent),
            ui(new Ui::Tree)
            {
            ui->setupUi(this);
            treeModel = new TreeModel();

            ui->treeView->setModel(treeModel);
            comboDelegate = new ComboBoxDelegate(ui->treeView);
            ui->treeView->setItemDelegateForColumn(0,  comboDelegate);
            
            QModelIndex index = ui->treeView->currentIndex();
            treeModel->insertRows(0,3,index);
            
            TreeItem* item = treeModel->itemForIndex(index);
            if(item->hasChildren())
            {
                index = treeModel->index(1,0,index);
                QVariant date = 2;
                treeModel->setData(index,date,Qt::CheckStateRole);
                date = "Name";
                treeModel->setData(index,date,Qt::EditRole);
                ui->treeView->update(index);
            }
            

            }@

            !http://hostingkartinok.com/show-image.php?id=67211b3f8729acd3651c75b5d788790a(Current dialog)!

            [URL=http://hostingkartinok.com/show-image.php?id=67211b3f8729acd3651c75b5d788790a][IMG]http://s1.hostingkartinok.com/uploads/thumbs/2015/03/67211b3f8729acd3651c75b5d788790a.png[/IMG][/URL]

            1 Reply Last reply
            0
            • H Offline
              H Offline
              House15
              wrote on 3 Mar 2015, 07:36 last edited by
              #6

              It may be useful to review the code of my model. Just in case.

              treemodel.h
              @
              #ifndef TREEITEM_H
              #define TREEITEM_H

              #include <QStandardItem>
              #include <QString>
              class TreeItem
              {
              public:
              //TreeItem(QList <QVariant> _m_itemData, TreeItem *parent = 0);
              TreeItem(QString &name, bool update=false, bool inners=false, TreeItem *parent = 0, int state = 0);
              ~TreeItem();
              QString name() const { return m_name; }
              int state() const { return _state; }
              void setName(const QString &name){m_name = name;}
              bool isUpdatable() const {return _update;}
              bool isInlinable() const {return _inners;}
              void setUpdatable(bool upd){ _update = upd; }
              void setInlines(bool inners){ _inners = inners; }

              TreeItem *parent() const {return m_parent;}
              TreeItem *child(int row) const {return m_children.value(row); }
              int rowOfChild(TreeItem *child) const {return m_children.indexOf(child);}
              int countOfChildren() {return m_children.count();}
              bool hasChildren() {return !m_children.empty();}
              QList<TreeItem*> children() const  {return m_children;}
              void insertChild(TreeItem *item, int row) {item->m_parent = this; m_children.insert(row,item);}
              void addChild(TreeItem *item) {item->m_parent = this; m_children<<item;}
              void swapChildren(int oldrow,  int newrow) {m_children.swap(oldrow,newrow);}
              TreeItem* takeChild(int row);
              

              private:
              QList <QVariant> m_itemData;
              QString m_name;
              bool _update;
              bool _inners;
              TreeItem m_parent;
              QList<TreeItem
              > m_children;
              // 0 - Non
              // 1 - Editable
              // 2 - inliable
              int _state;
              };

              #endif // TREEITEM_H
              @

              1 Reply Last reply
              0
              • H Offline
                H Offline
                House15
                wrote on 3 Mar 2015, 07:36 last edited by
                #7

                treemodel.cpp
                @
                #include "treemodel.h"

                QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const
                {
                if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
                {
                if(section == State)
                return "Состояние";
                if(section == Name)
                return "Наименование";
                }
                return QVariant();
                }

                Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
                {

                Qt::ItemFlags theFlags = QAbstractItemModel::flags(index);
                if(index.isValid())
                {
                    theFlags |= Qt::ItemIsSelectable|Qt::ItemIsEnabled;
                   // if(index.column() == State)
                       // theFlags |= Qt::ItemIsUserCheckable|Qt::ItemIsTristate;
                        //theFlags |= Qt::ItemIsUserCheckable|Qt::ItemIsEditable|Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled;
                }
                
                return theFlags;
                

                }

                QVariant TreeModel::data(const QModelIndex &index, int role) const
                {
                if(!rootItem || !index.isValid() || index.column() > 0 || index.column() >= ColumnCount)
                return QVariant();

                if(TreeItem *Item = itemForIndex(index))
                {
                    if(role == Qt::DisplayRole || role == Qt::EditRole)
                    {
                        switch(index.column())
                        {
                        case Name: return Item->name();
                        case State: return Item->state();
                        default: Q_ASSERT(false);
                        }
                    }
                
                    if(role == Qt::CheckStateRole && index.column() == State)
                    {
                        bool update = false;
                        bool iline = false;
                
                        update = static_cast<bool>(Item->isUpdatable());
                        iline = static_cast<bool>(Item->isInlinable());
                        if(!update&&!iline) return 0;
                        else if(update) return 1;
                        else if (iline) return 2;
                        else if(update&&iline) return QVariant();
                    }
                }
                return QVariant();
                

                }

                TreeItem* TreeModel::itemForIndex(const QModelIndex &index) const
                {
                if(index.isValid())
                {
                if(TreeItem item = static_cast<TreeItem>(index.internalPointer()))
                {
                return item;
                }
                }
                return rootItem;
                }

                int TreeModel::rowCount(const QModelIndex &parent) const
                {
                if(parent.isValid() && parent.column() != 0)
                return 0;

                TreeItem *parentItem = itemForIndex(parent);
                return parentItem ? parentItem->countOfChildren() : 0;
                

                }

                int TreeModel::columnCount(const QModelIndex &parent) const
                {
                return parent.isValid() && parent.column() != 0? 0:ColumnCount;
                }

                int TreeModel::stateIs(const QModelIndex &index, int role) const
                {
                if(!index.isValid())
                return -1;

                int state = data(index, Qt::CheckStateRole).toInt();
                
                return state;
                

                }

                bool TreeModel::insertRows(int row, int count, const QModelIndex &parent)
                {
                if(!rootItem)
                {
                QString RootName("Root");
                rootItem = new TreeItem(RootName,false,false,(TreeItem*)0,0);
                if(!rootItem)
                {
                return false;
                }
                }

                QString newElem("New elem");
                TreeItem *parentItem = parent.isValid() ? itemForIndex(parent) : rootItem;
                QAbstractItemModel::beginInsertRows(parent,row,row+count-1);
                for(int i=0; i<count;++i)
                {
                    TreeItem *item = new TreeItem(newElem,false);
                    parentItem->insertChild(item,row);
                }
                endInsertRows();
                return true;
                

                }

                bool TreeModel::addBranchToRoot(TreeItem &items)
                {
                return false;
                }

                bool TreeModel::removeRows(int row, int count, const QModelIndex &parent)
                {
                if(!rootItem)
                return false;

                TreeItem *item = parent.isValid() ? itemForIndex(parent) : rootItem;
                QAbstractItemModel::beginRemoveRows(parent,row,row+count-1);
                for(int i=0; i<count; i++)
                    delete item->takeChild(row);
                
                QAbstractItemModel::endRemoveRows();
                return true;
                

                }

                QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
                {
                if(!rootItem || row<0 || column < 0 || column >=ColumnCount || (parent.isValid() && parent.column() !=0))
                return QModelIndex();

                TreeItem *parentItem = itemForIndex(parent);
                Q_ASSERT(parentItem);
                if(TreeItem *item = parentItem->child(row)){
                    return createIndex(row,column,item);
                }
                
                return QModelIndex();
                

                }

                QModelIndex TreeModel::parent(const QModelIndex &index) const
                {
                if(!index.isValid())
                return QModelIndex();

                if(TreeItem *childItem = itemForIndex(index))
                {
                    if(TreeItem *parentItem = childItem->parent())
                    {
                        if(parentItem == rootItem)
                            return QModelIndex();
                
                        if(TreeItem *grandParentItem = parentItem->parent()){
                            int row = grandParentItem->rowOfChild(parentItem);
                            return createIndex(row,0,parentItem);
                        }
                    }
                }
                return QModelIndex();
                

                }

                bool TreeModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
                {return false;}

                bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
                {
                if(!index.isValid() || index.column() != State)
                return false;

                if(TreeItem *item =  itemForIndex(index))
                {
                    if(role == Qt::EditRole)
                        item->setName(value.toString());
                    else if(role == Qt::CheckStateRole)
                    {
                        switch(value.toInt())
                        {
                        case 0:
                        {
                            item->setUpdatable(false);
                            item->setInlines(false);
                        }
                            break;
                        case 1:
                        {
                            item->setUpdatable(true);
                            item->setInlines(false);
                        }
                            break;
                        case 2:
                        {
                            item->setUpdatable(false);
                            item->setInlines(true);
                        }
                            break;
                        }
                    }
                    else
                        return false;
                
                    emit dataChanged(index,index);
                    return true;
                }
                return false;
                

                }

                @

                1 Reply Last reply
                0
                • H Offline
                  H Offline
                  House15
                  wrote on 3 Mar 2015, 08:25 last edited by
                  #8

                  I also noticed a strange thing. If we define the editor, using the method of the delegate, it will appear in the specified model index position. In this case - in the header. There was a question: Is not the model itself must initialize a delegate in the correct position? In the manual it is also possible to do, but it is not convenient, and contradicts the logic of the method "setItemDelegateForColumn."

                  I'm talking about the code on line 10:
                  comboDelegate->createEditor(ui->treeView,QStyleOptionViewItem(),QModelIndex());

                  @Tree::Tree(QWidget *parent) :
                  QDialog(parent),
                  ui(new Ui::Tree)
                  {
                  ui->setupUi(this);
                  treeModel = new TreeModel();
                  ui->treeView->setModel(treeModel);

                  comboDelegate = new ComboBoxDelegate(ui->treeView);
                  comboDelegate->createEditor(ui->treeView,QStyleOptionViewItem(),QModelIndex());
                  ui->treeView->setItemDelegateForColumn(0,  comboDelegate);
                  
                  QModelIndex index = ui->treeView->currentIndex();
                  treeModel->insertRows(0,3,index);
                  
                  TreeItem* item = treeModel->itemForIndex(index);
                  if(item->hasChildren())
                  {
                      index = treeModel->index(1,0,index);
                      QVariant date = 2;
                      treeModel->setData(index,date,Qt::CheckStateRole);
                      date = "Name";
                      treeModel->setData(index,date,Qt::EditRole);
                      ui->treeView->update(index);
                  }
                  

                  }@

                  1 Reply Last reply
                  0
                  • H Offline
                    H Offline
                    House15
                    wrote on 3 Mar 2015, 13:25 last edited by
                    #9

                    I am totally confused. Not only that delegates are not displayed, so even when you remove elements of wood, the application crashes. Nothing catch up.

                    @
                    Tree::Tree(QWidget *parent) :
                    QDialog(parent),
                    ui(new Ui::Tree)
                    {
                    ui->setupUi(this);
                    treeModel = new TreeModel(this);

                    comboDelegate = new ComboBoxDelegate(ui->treeView);
                    ui->treeView->setItemDelegateForColumn(0,  comboDelegate);
                    
                    QModelIndex index = ui->treeView->currentIndex();
                    ui->treeView->setRootIndex(index);
                    ui->treeView->setModel(treeModel);
                    

                    }
                    @

                    @void Tree::removeItem()
                    {
                    QModelIndex currentIndex = ui->treeView->currentIndex();
                    if(!currentIndex.isValid())
                    return;

                    treeModel->removeRows(currentIndex.row(),1,currentIndex.parent());
                    ui->treeView->update();
                    

                    }@

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 11 Mar 2015, 23:38 last edited by
                      #10

                      From your model code, your items are not editable so there's no editor that can appear.

                      For your crash, are you sure that treeModel points to something valid ?

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      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