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. How to update two items in an index with use of QStyledItemDelegate and QAbstractItemModel ?
Forum Updated to NodeBB v4.3 + New Features

How to update two items in an index with use of QStyledItemDelegate and QAbstractItemModel ?

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 4 Posters 1.2k 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.
  • P Offline
    P Offline
    Pauly
    wrote on last edited by
    #1

    I customized a QStyledItemDelegate and QAbstractItemModel for a QTreeView. I have a qwidget that contain a qcolor box and a qlineedit for a given row (index), I'm trying to save color and lineedit text to variables. However I can not update the text into variable... (see code below)

    I think the problem is that when the text item is edited, the first "model->setData" for color variable in QStyledItemDelegate "setModelData" function is always executed first, which triggers the "data" function, which returns the original text and QStyledItemDelegate "setEditorData" will overwrite modified text.

    I'm thinking I need to tell what is changed in QStyledItemDelegate "setModelData" function so the right setdata can be sent? How can I do that? Or what is the right way to do this?

    in QStyledItemDelegate .cpp:

    ...

    void MyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    {
        MyWidget *widget = static_cast<MyWidget *>(editor);
        widget->blockSignals(true);
        widget->setMyText(index.data(Qt::EditRole).toString());
        widget->setMyColor(index.data(Qt::UserRole).value<QColor>());
        widget->blockSignals(false);
    }
    
    void MyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
              const QModelIndex &index) const
    {
    model->setData(index, QVariant(static_cast<MyWidget*>(editor)->getMyColor()), Qt::UserRole);
    model->setData(index, QVariant(static_cast<MyWidget*>(editor)->getMyText()), Qt::EditRole);
    }
    

    in QAbstractItemModel .cpp:

    QVariant MyModel::data(const QModelIndex &index, int role) const
    {
    if (role == Qt::EditRole){
    return myTextVariable;
    }
    
    if (role == Qt::UserRole){
    return myColorVariable;
    }
    
    return QVariant();
    }
    
    bool myModel::setData(const QModelIndex& index, const QVariant& value, int role)
    {
    if (role == Qt::UserRole){
        myColorVariable=value.value<QColor>();
    }else if (role == Qt::EditRole){
        myTextVariable=value.toString();
    }
    }
    Q_EMIT dataChanged(index, index);
    return true;
    }
    
    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Pauly said in How to update two items in an index with use of QStyledItemDelegate and QAbstractItemModel ?:

      setEditorData

      Here you're already using blockSignals() - you can try this for model too. Or remember in a member that you're currently setting the data.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      0
      • P Offline
        P Offline
        Pauly
        wrote on last edited by
        #3

        Do you mean to block signal for setdata call in MyDelegate::setModelData? Won't that block updating one variable or the other?

        I think I would still need to know what got changed in MyDelegate to set such a member? How can I tell? Thanks.

        1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #4

          Why do you need to block the signals? are you connecting the editor to the delegate? can you show MyDelegate::createEditor?

          Also, your myModel::setData and MyModel::data do not use the index supplied at all, is it a 1 row, 1 column model?

          "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
          0
          • P Offline
            P Offline
            Pauly
            wrote on last edited by Pauly
            #5

            I do not recall why I block the signal... maybe I just copied this from somewhere...

            I did not think the createEditor matters to the question so I skip that code. But here is it:

            QWidget *MyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
            {
                    MyWidget *editor = new MyWidget(index, parent);
                    editor->setEditorText("text");
                    editor->setColor(QColor(Qt::black));
                    return editor;
                }
            
            return new QWidget(parent);
            }
            

            In reality it is more than one row... I skipped the index here and let's just consider it as one row, it doesn't change the situation, does it? Thank you.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by SGaist
              #6

              Hi,

              Since you want to modify two elements in one shot, why not pass a QPair to the user role with the two values and let the model put that in the correct places ?

              As @VRonin suggests below: setItemData is the right tool.

              [edit: Fixed suggestions SGaist]

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

              VRoninV 1 Reply Last reply
              1
              • P Offline
                P Offline
                Pauly
                wrote on last edited by Pauly
                #7

                Great idea! Along with the same thought, I use QList (just in case if more than two variables to be updated) and it works. This is the new code. Thanks!

                in QStyledItemDelegate .cpp:

                void MyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
                {
                MyWidget *widget = static_cast<MyWidget *>(editor);
                widget->blockSignals(true);
                widget->setColor(index.data(Qt::EditRole).toList().at(0).value<QColor>());
                widget->setText(index.data(Qt::EditRole).toList().at(1).toString());
                widget->blockSignals(false);
                }
                
                void MyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const
                {
                listData<<QVariant(static_cast<MyWidget*>(editor)->getColor())<<QVariant(static_cast<MyWidget*>(editor)->getText());
                		
                model->setData(index, QVariant(listData), Qt::EditRole);
                }
                

                in QAbstractItemModel .cpp:

                QVariant MyModel::data(const QModelIndex &index, int role) const
                {
                QList<QVariant> listData;
                listData<<QVariant(myColor)<<QVariant(myText);
                return listData;
                }
                
                bool myModel::setData(const QModelIndex& index, const QVariant& value, int role)
                {
                myColor=value.toList().at(0).value<QColor>();
                myText=value.toList().at(1).toString();
                }
                Q_EMIT dataChanged(index, index);
                return true;
                }
                
                1 Reply Last reply
                0
                • SGaistS SGaist

                  Hi,

                  Since you want to modify two elements in one shot, why not pass a QPair to the user role with the two values and let the model put that in the correct places ?

                  As @VRonin suggests below: setItemData is the right tool.

                  [edit: Fixed suggestions SGaist]

                  VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by
                  #8

                  @SGaist said in How to update two items in an index with use of QStyledItemDelegate and QAbstractItemModel ?:

                  Since you want to modify two elements in one shot, why not pass a QPair

                  Are you suggesting a reinvention of https://doc.qt.io/Qt-5/qabstractitemmodel.html#setItemData ?

                  "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
                  1
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    I knew I was forgetting something !

                    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