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. QTableView : cell previous value keep showing when editing
Forum Updated to NodeBB v4.3 + New Features

QTableView : cell previous value keep showing when editing

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 2 Posters 1.4k 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.
  • N Offline
    N Offline
    natxo14
    wrote on last edited by
    #1

    Hello,
    Platform: Linux Mint 5.4.0-89-generic #100-Ubuntu SMP
    QtCreator: 4.15.1
    Qt Version : 5.12.8 AND Qt 5.15.2

    I'm working with Model/View classes, trying to display a 5 column table with different type of data: Strings, Floats and Booleans.

    I've selected the following classes :
    A standard QTableView.
    A custom QAbstractTableModel.
    A custom QStyledItemDelegate for the float column to use a QSpinBox as value editor.

    The delegate is exactly the same as the one in the spinboxdeleate qt example.

    For the custom QAbstractTableModel, I've overwritten the following functions:

    int rowCount(const QModelIndex &p_parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &p_parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &p_index, int p_role = Qt::DisplayRole) const override;
    QVariant headerData(int p_section, Qt::Orientation orientation, int p_role) const override;
    bool setData(const QModelIndex &p_index, const QVariant &p_value, int p_role = Qt::EditRole) override;
    Qt::ItemFlags flags(const QModelIndex &p_index) const override;
    bool insertRows(int p_position, int p_rows, const QModelIndex &p_index = QModelIndex()) override;
    

    Data is stored in a private QList<Sample> m_data structure .Sample is just a struct with 2 QStrings, 1 float and 2 booleans.
    Relevant code for the overwritten functions is:

    QVariant CTrayEditorModel::data(const QModelIndex &p_index, int p_role) const
    {
        if (checkIndex(p_index))
        {
            // use both Display and EditRole to show data when editing
            if (p_role == Qt::DisplayRole || p_role == Qt::EditRole)
            {
                switch (p_index.column())
                {
                    case 0:
                        return sample.m_well;
                    case 1:
                        return sample.m_name;
                    case 2:
                        return sample.m_concentration;
                    default:
                        break;
                }
            }
            // use this role to display checkboxes in two last columns
            else if (p_role == Qt::CheckStateRole)
            {
                if (p_index.column() == 3)
                    return sample.m_isBuffer ? Qt::Checked : Qt::Unchecked;
                if (p_index.column() == 4)
                    return sample.m_isViscous ? Qt::Checked : Qt::Unchecked;
            }
            else if (p_role == Qt::TextAlignmentRole)
            {
                return Qt::AlignCenter;
            }
        }
        return QVariant();
    }
    bool CTrayEditorModel::setData(const QModelIndex &p_index, const QVariant &p_value, int p_role)
    {
        if (p_index.isValid())
        {
            if (!checkIndex(p_index))
                return false;
    
            const int row = p_index.row();
            //  on insertRows an empty element has been added to 
            auto sample   = m_data.value(row);
    
            if (p_role == Qt::EditRole)
            {
                switch (p_index.column())
                {
                    case 0:
                        sample.m_well = p_value.toString();
                        break;
                    case 1:
                        sample.m_name = p_value.toString();
                        break;
                    case 2:
                        sample.m_concentration = p_value.toFloat();
                        break;
                    default:
                        return false;
                }
            }
            if (p_role == Qt::CheckStateRole)
            {
                switch (p_index.column())
                {
                    case 3:
                        sample.m_isBuffer = p_value.toBool();
                        break;
                    case 4:
                        sample.m_isViscous = p_value.toBool();
                        break;
                    default:
                        return false;
                }
            }
            m_data.replace(row, sample);
            return true;
        }
        return false;
    }
    Qt::ItemFlags CTrayEditorModel::flags(const QModelIndex &p_index) const
    {
        // first column not editable
        if (p_index.column() == 0)
        {
            return (QAbstractTableModel::flags(p_index) & ~Qt::ItemIsEditable);
        }
        // 4th and 5th columns checkboxes
        else if (p_index.column() == 3 || p_index.column() == 4)
        {
            return (QAbstractTableModel::flags(p_index) | Qt::ItemIsUserCheckable);
        }
         // 2nd column editable string
         else if (p_index.column() == 1)
        {
            return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
        }
        // 3rd column spinbox
        else
        {
            return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | QAbstractTableModel::flags(p_index);
        }
    }
    

    Code setting up the table:

    m_modelView = new QTableView();
    m_modelView->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_modelView->horizontalHeader()->setStretchLastSection(true);
    m_modelView->verticalHeader()->hide();
    
    m_trayModel = new CTrayEditorModel(this);
    m_modelView->setModel(m_trayModel);
        
    //delegate
    CTrayEditorDelegate* delegate = new CTrayEditorDelegate();
    m_modelView->setItemDelegateForColumn(2, delegate);
    

    The issue:
    Using Qt 5.12.8 when editing cells, both the ones with string contents and the one with the spinboxdelegate, when changing the content of the cell, the previous value keeps showing, like if the default 'show delegate' was not 'covered' by the edit delegate.
    See screenshot for better understanding.

    But compiling same code with Qt 5.15.2 , it works as expected.

    I've been looking for known bugs of Qt 5.12.8 and I found nothing related to this. As I'm stuck with that Qt version for my project, I'm looking for a solution for this...

    If more code needs to be given, don't hesitate to ask: I was trying not to make the post very long.
    QTableViewBug.png

    Thanks!

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

      @natxo14 said in QTableView : cell previous value keep showing when editing:

      Is it worth opening it??

      As I said I fixed it somewhen in between. So upgrade to latest 5.12.x will most likely fix it.

      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
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Please take a look at the documentation to setData():

        "The dataChanged() signal should be emitted if the data was successfully set."

        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
        2
        • N Offline
          N Offline
          natxo14
          wrote on last edited by natxo14
          #3

          Hi Christian,
          Thanks for your quick answer.
          I did change my code on setData() function to:

          if (p_index.isValid())
          {
              ///...if (p_role == Qt::EditRole){} ... if (p_role == Qt::CheckStateRole){}
              m_data.replace(row, sample);
              qDebug() << "setData p_index : " << p_index.row() << "," << p_index.column() << ":" << p_role;
              QVector<int> roles = {p_role};
              emit dataChanged(p_index, p_index, roles);
              return true;
          }
          

          I have also added some debug code : it's only called (it prints what I've asked) only when the edition of the cell ends. But the bug/display issue happens while the edition happens.

          As per the doc

          When displaying data from models in Qt item views, e.g., a QTableView, the individual items are drawn by a delegate. 
          Also, when an item is edited, it provides an editor widget, which is placed on top of the item view while editing takes place. 
          QStyledItemDelegate is the default delegate for all Qt item views, and is installed upon them when they are created.
          

          So I don't know if this is a bug (the 'display' default delegate does not 'hide' behind the 'edit' delegate for Qt 5.12 but it works for Qt 5.15) or if I'm still missing something in my code...

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

            What exact version of 5.12 do you use? I know there was such a bug somewhere in 5.12 but can't find the bug report for now.

            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
            • N Offline
              N Offline
              natxo14
              wrote on last edited by
              #5

              Thanks for your answer, Christian.

              From CMakeList.txt file:

              message(STATUS "Qt5 COMPONENTS VERSIONS")
              message(STATUS "Core: ${Qt5Core_VERSION_STRING}")
              message(STATUS "Widgets: ${Qt5Widgets_VERSION_STRING}")
              

              Output:

              -- Qt5 COMPONENTS VERSIONS
              -- Core: 5.12.8
              -- Widgets: 5.12.8

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

                Can you try another style (e.g. windows) to see if it is fixed then. I really can't find the bug report anymore :)

                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
                • N Offline
                  N Offline
                  natxo14
                  wrote on last edited by
                  #7

                  Hi,
                  I've executed the app with -style windows on the command line and it works as expected: the previous texts disappears and the edition of the cell content goes as expected.
                  Thanks for the clue, I'll think about it next time before wasting a couple of workdays :)

                  Should this be considered as a bug?? Is it worth opening it??
                  Thanks!

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

                    @natxo14 said in QTableView : cell previous value keep showing when editing:

                    Is it worth opening it??

                    As I said I fixed it somewhen in between. So upgrade to latest 5.12.x will most likely fix it.

                    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

                    • Login

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