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. Using a custom data type and editor in QStandardItemModel

Using a custom data type and editor in QStandardItemModel

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 3 Posters 2.3k 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.
  • L Offline
    L Offline
    Lurkki
    wrote on last edited by
    #1

    I'm using a custom data type in the items of a QStandardItemModel, but setting item data for different roles seems to affect the data of all roles, and setting the text for the items seems to overwrite the data as well. What's the correct way of doing this?

    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      How do you set the data? Please show some code.

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

      L 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        How do you set the data? Please show some code.

        L Offline
        L Offline
        Lurkki
        wrote on last edited by Lurkki
        #3

        @Christian-Ehrlicher
        Setting the data initially:

            std::function<void(tc_assignable_node_t*, QStandardItem*)> traverse;
            traverse = [=, &traverse](tc_assignable_node_t *node, QStandardItem *item) {
                if (node == NULL) {
                    return;
                }
                
                if (node->name != NULL) { 
                    qDebug() << node->name;
                }
                
                // List for adding the name and editor on the same row
                QList <QStandardItem*> rowItems;
                
                QStandardItem *nameItem = new QStandardItem;
                nameItem->setText(node->name);
                nameItem->setEditable(false);
                rowItems.append(nameItem);
                
                // Don't add editor item for TC_ASSIGNABLE_NONE nodes
                if (node->value_category != TC_ASSIGNABLE_NONE) {
                    QStandardItem *editorItem = new QStandardItem;
                    QVariant v;
                    AssignableData data(node);
                    v.setValue(data);
                    editorItem->setData(v, Qt::EditRole);
                    //editorItem->setText(node->name);
                    rowItems.append(editorItem);
                }
                
                item->appendRow(rowItems);
                
                for (uint32_t i = 0; i < node->children_count; i++) {
                    traverse(node->children_nodes[i], nameItem);
                }
            };
        

        setModelData() of my delegate:

            AssignableData data = qvariant_cast<AssignableData>(index.model()->data(index));
            QVariant v;
            QStandardItemModel *s_model = static_cast<QStandardItemModel*>(model);
        ...
        IntRangeEditor *ed = static_cast<IntRangeEditor*>(editor);
                            data.setValue(ed->value());
                            v.setValue(data);
                            s_model->setData(index, v, Qt::EditRole);
                            //s_model->itemFromIndex(index)->setText("");
        

        without the last line uncommented, it seems to overwrite the item's entire data and it becomes ineditable

        1 Reply Last reply
        0
        • Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Lurkki said in Using a custom data type and editor in QStandardItemModel:

          without the last line uncommented,

          You mean '//s_model->itemFromIndex(index)->setText("");' ?
          This will set the Qt::DisplayRole and Qt::EditRole as explained in the documentation

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

          L 1 Reply Last reply
          1
          • Christian EhrlicherC Christian Ehrlicher

            @Lurkki said in Using a custom data type and editor in QStandardItemModel:

            without the last line uncommented,

            You mean '//s_model->itemFromIndex(index)->setText("");' ?
            This will set the Qt::DisplayRole and Qt::EditRole as explained in the documentation

            L Offline
            L Offline
            Lurkki
            wrote on last edited by
            #5

            @Christian-Ehrlicher s_model->setData(index,"a", Qt::DisplayRole); has the same effect, it overwrites my custom data

            Christian EhrlicherC 1 Reply Last reply
            0
            • mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi
              I might have missed something but i only see you using
              Qt::EditRole
              so where is this custom data stored and in what way
              "becomes ineditable" its still shown but you can type in it or ?

              L 1 Reply Last reply
              0
              • mrjjM mrjj

                Hi
                I might have missed something but i only see you using
                Qt::EditRole
                so where is this custom data stored and in what way
                "becomes ineditable" its still shown but you can type in it or ?

                L Offline
                L Offline
                Lurkki
                wrote on last edited by
                #7

                @mrjj My mistake, yeah I can edit it but my custom data disappears. The data is stored in the model.

                1 Reply Last reply
                0
                • L Lurkki

                  @Christian-Ehrlicher s_model->setData(index,"a", Qt::DisplayRole); has the same effect, it overwrites my custom data

                  Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @Lurkki said in Using a custom data type and editor in QStandardItemModel:

                  has the same effect, it overwrites my custom data

                  I would say it's a bug if it's not - see the documentation...

                  Note: The default implementation treats Qt::EditRole and Qt::DisplayRole as referring to the same data.

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

                  L 1 Reply Last reply
                  0
                  • Christian EhrlicherC Christian Ehrlicher

                    @Lurkki said in Using a custom data type and editor in QStandardItemModel:

                    has the same effect, it overwrites my custom data

                    I would say it's a bug if it's not - see the documentation...

                    Note: The default implementation treats Qt::EditRole and Qt::DisplayRole as referring to the same data.

                    L Offline
                    L Offline
                    Lurkki
                    wrote on last edited by Lurkki
                    #9

                    @Christian-Ehrlicher How should I go about subclassing QStandardItem and reimplementing setData then? I can't seem to find much information about it.

                    mrjjM 1 Reply Last reply
                    0
                    • L Lurkki

                      @Christian-Ehrlicher How should I go about subclassing QStandardItem and reimplementing setData then? I can't seem to find much information about it.

                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by mrjj
                      #10

                      @Lurkki

                      Hi
                      Can you please make a small example showing this ?,

                      I have a bad feeling its just incorrect use / expectations and
                      not an actual bug.

                      Qt::EditRole and Qt::DisplayRole is the same so that is expected.

                      try to use Qt::UserRole for your custom data end see.

                      To use custom data, you can use

                      setData(index,"a", Qt::UserRole );
                      setData(index,"a", Qt::UserRole +1);
                      setData(index,"a", Qt::UserRole +2);

                      L 1 Reply Last reply
                      2
                      • mrjjM mrjj

                        @Lurkki

                        Hi
                        Can you please make a small example showing this ?,

                        I have a bad feeling its just incorrect use / expectations and
                        not an actual bug.

                        Qt::EditRole and Qt::DisplayRole is the same so that is expected.

                        try to use Qt::UserRole for your custom data end see.

                        To use custom data, you can use

                        setData(index,"a", Qt::UserRole );
                        setData(index,"a", Qt::UserRole +1);
                        setData(index,"a", Qt::UserRole +2);

                        L Offline
                        L Offline
                        Lurkki
                        wrote on last edited by Lurkki
                        #11

                        @mrjj Thanks, that works for my use case

                        Setting the data:

                                if (node->value_category != TC_ASSIGNABLE_NONE) {
                                    QStandardItem *editorItem = new QStandardItem;
                                    QVariant v;
                                    AssignableData data(node);
                                    v.setValue(data);
                                    editorItem->setData(v, Qt::UserRole);
                                    //editorItem->setText(node->name);
                                    rowItems.append(editorItem);
                                }
                        
                        

                        Setting editor data in the delegate:

                        void AssignableEditorDelegate::setEditorData(QWidget* editor, const QModelIndex &index) const {
                            AssignableData data = qvariant_cast<AssignableData>(index.model()->data(index, Qt::UserRole));
                            
                            switch (data.m_valueCategory) {
                                case TC_ASSIGNABLE_RANGE:
                                    switch (data.m_rangeInfo.range_data_type) {
                                        case TC_ASSIGNABLE_RANGE_INT: {
                                            IntRangeEditor *ed = static_cast<IntRangeEditor*>(editor);
                                            ed->setValue(data.value().toInt());
                                            break;
                                        }
                                        default:
                                            break;
                                    }
                                default:
                                    break;
                            }
                        }
                        

                        Setting model data:

                        void AssignableEditorDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
                            AssignableData data = qvariant_cast<AssignableData>(index.model()->data(index, Qt::UserRole));
                            QVariant v;
                            QStandardItemModel *s_model = static_cast<QStandardItemModel*>(model);
                            
                            switch (data.m_valueCategory) {
                                ...
                                case TC_ASSIGNABLE_RANGE:
                                    switch (data.m_rangeInfo.range_data_type) {
                                        case TC_ASSIGNABLE_RANGE_INT: {
                                            IntRangeEditor *ed = static_cast<IntRangeEditor*>(editor);
                                            data.setValue(ed->value());
                                            v.setValue(data);
                                            s_model->setData(index, v, Qt::UserRole);
                                            s_model->setData(index, ed->value(), Qt::DisplayRole);
                                            break;
                                            }
                                        default:
                                            break;
                                    }
                                default:
                                    break;
                            }
                        }
                        

                        I also had to do setAutoFillBackground(true); in my editor widget to make the display text not overlap with the editor.

                        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