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. Show live data into a table
Qt 6.11 is out! See what's new in the release blog

Show live data into a table

Scheduled Pinned Locked Moved Solved General and Desktop
34 Posts 5 Posters 6.9k Views 2 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.
  • M makopo

    Hi everyone,

    I want to show data (some results of mathematical operations) into a table. This data should updated every second. And I am not sure if the signal and slot principle is the correct way, or if delegates (model/view programming) do a better job for this.
    In my program I have a method that calculates a value and emit a signal with this value as parameter. The slot that receives casts the integer value into a string (with QVartiant) and this string is inserted a item into a table cell.
    I use no database or csv-file. All values that are calculated should shown directly to the frontend.

    Is this a good style doing this?

    JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by JonB
    #3

    @makopo
    For best results, you should derive from QAbstractTableModel to create your own model. Then bind a QTableView to that to show the data. When you add/update data in your model that will raise signals for you which are attached to the table view, and that will update whenever it sees a change in the model.

    If speed is not an issue, you can simplify by using a QStandardItemModel for your data instead of your own QAbstractTableModel, or even a QTableWidget to wrap the model + view into one. You might start out with these if you are a beginner, and maybe upgrade to a QAbstractTableModel/QTableView when you are ready for better performance/typing.

    1 Reply Last reply
    1
    • M Offline
      M Offline
      makopo
      wrote on last edited by makopo
      #4

      Great! I'd read the documentation of the model/view paradigm, but it ws not clear for me that this also works without databases.

      Thank you @SGaist and @JonB !

      1 Reply Last reply
      0
      • M Offline
        M Offline
        makopo
        wrote on last edited by
        #5

        Hi there,

        is there a functionality to add a QTableView to a GridLayout? I create a QTableView successfully with the following lines but this (logically) creates a new window.

        m_tableView->setModel(m_tableDataModel);
        m_tableView->show();
        
        JonBJ 1 Reply Last reply
        0
        • M makopo

          Hi there,

          is there a functionality to add a QTableView to a GridLayout? I create a QTableView successfully with the following lines but this (logically) creates a new window.

          m_tableView->setModel(m_tableDataModel);
          m_tableView->show();
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #6

          @makopo
          What is a GridLayout? If you mean QGridLayout, that is a QLayout. QTableView is a QWidget. You can always add a QWidget to a QLayout.

          M 1 Reply Last reply
          1
          • JonBJ JonB

            @makopo
            What is a GridLayout? If you mean QGridLayout, that is a QLayout. QTableView is a QWidget. You can always add a QWidget to a QLayout.

            M Offline
            M Offline
            makopo
            wrote on last edited by makopo
            #7

            What a silly question of mine! I tried it few hours ang and adding QTableView to QGridLayout did not work. Now it works... Thank you

            Thank YouT 1 Reply Last reply
            0
            • M makopo

              What a silly question of mine! I tried it few hours ang and adding QTableView to QGridLayout did not work. Now it works... Thank you

              Thank YouT Offline
              Thank YouT Offline
              Thank You
              wrote on last edited by
              #8

              @makopo If it is solved then mark it as solved. So others can give time on other unsolved question 💥😀

              Let's make QT free or It will go forever

              TRUE AND FALSE <3

              1 Reply Last reply
              0
              • M Offline
                M Offline
                makopo
                wrote on last edited by
                #9

                Unfortunatly the view did not work like expected. I create a data model (derived from QAbstractTableModel) and with this model I can generate a table view. But this view is static and values did not update.
                I change, for example, the video mode of the stream and on the console this change is detected. In the table view the initial state is detected and did not change.
                I make QTableView editable, but I think that this is not the right way for my requirement.

                I implement the virtual data function like this:

                QVariant DataTableModel::data(const QModelIndex& index, int role) const
                {
                    if (!index.isValid()) {
                        return QVariant();
                    }
                
                    if (index.row() >= m_parameter.size() && index.row() >= m_value.size()) {
                        return QVariant();
                    }
                
                    if (role == Qt::DisplayRole || role == Qt::EditRole) {
                        if (index.column() == 0) {
                            return m_parameter.at(index.row());
                        }
                
                        if (index.column() == 1) {
                            return m_value.at(index.row());
                        }
                    }
                    return QVariant();
                }
                

                In the main class I create two QVector types that stores the values for the table cells.

                QVector<QString> parameters;
                Qvector<QString> values;
                parameters.append("Video mode");
                values.append(QVariant(m_displayMode->GetDisplayMode()).toString());
                
                m_tableDataModel->AddData(parameters, values);
                m_tableView->setModel(m_tableDataModel);
                

                As descipted I get the initial video mode, but after changing the mode the state is not updated.
                Is there a restiction with the data types and the update process?

                kshegunovK 1 Reply Last reply
                0
                • M makopo

                  Unfortunatly the view did not work like expected. I create a data model (derived from QAbstractTableModel) and with this model I can generate a table view. But this view is static and values did not update.
                  I change, for example, the video mode of the stream and on the console this change is detected. In the table view the initial state is detected and did not change.
                  I make QTableView editable, but I think that this is not the right way for my requirement.

                  I implement the virtual data function like this:

                  QVariant DataTableModel::data(const QModelIndex& index, int role) const
                  {
                      if (!index.isValid()) {
                          return QVariant();
                      }
                  
                      if (index.row() >= m_parameter.size() && index.row() >= m_value.size()) {
                          return QVariant();
                      }
                  
                      if (role == Qt::DisplayRole || role == Qt::EditRole) {
                          if (index.column() == 0) {
                              return m_parameter.at(index.row());
                          }
                  
                          if (index.column() == 1) {
                              return m_value.at(index.row());
                          }
                      }
                      return QVariant();
                  }
                  

                  In the main class I create two QVector types that stores the values for the table cells.

                  QVector<QString> parameters;
                  Qvector<QString> values;
                  parameters.append("Video mode");
                  values.append(QVariant(m_displayMode->GetDisplayMode()).toString());
                  
                  m_tableDataModel->AddData(parameters, values);
                  m_tableView->setModel(m_tableDataModel);
                  

                  As descipted I get the initial video mode, but after changing the mode the state is not updated.
                  Is there a restiction with the data types and the update process?

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by kshegunov
                  #10

                  @makopo said in Show live data into a table:

                  Is there a restiction with the data types and the update process?

                  Of course, adding something to a vector notifies nobody. If you'd kept an int and changed it, the result'd be the same. To add to the model define your addRow or alike and thereafter follow the documentation. There's a battery of signals that the model must emit so the view gets notified of changes - beginInsertRows, endInsertRows and so on.

                  Read and abide by the Qt Code of Conduct

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

                    On addition to @kshegunov you also need to re-implement setData so that you can properly notify when data changes.

                    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
                    3
                    • M Offline
                      M Offline
                      makopo
                      wrote on last edited by makopo
                      #12

                      I did not understand how to implement insertRows() correctly and it also looks like that the function is not called. Because the QAbstractTableModel did not work, I rebuild the Qt tutorial which uses the QAbstractListModel.

                      In insertRows() I call beginInsertRows(), than I run the loop and than I call endInsertRows().

                      bool DataTableModel::insertRows(int position, int rows, const QModelIndex& parent)
                      {
                          beginInsertRows(QModelIndex(), position, position + rows - 1);
                          for (int x = 1; x <= 10; ++x) {
                              m_stringList.push_back(QString::number(x));
                          }
                          endInsertRows();
                          qDebug() << "insertRows is called.";
                      
                          return true;
                      }
                      

                      As result I get an empty List. On console I can also see that the function is not called. So my question is, how to handle insertRows() function? Did stringList.insert(position, ""); from the Model/View Programming tutorial only reservs an empty line? I thought that there is the entry-point where I have to insert the data.

                      JonBJ 1 Reply Last reply
                      0
                      • M makopo

                        I did not understand how to implement insertRows() correctly and it also looks like that the function is not called. Because the QAbstractTableModel did not work, I rebuild the Qt tutorial which uses the QAbstractListModel.

                        In insertRows() I call beginInsertRows(), than I run the loop and than I call endInsertRows().

                        bool DataTableModel::insertRows(int position, int rows, const QModelIndex& parent)
                        {
                            beginInsertRows(QModelIndex(), position, position + rows - 1);
                            for (int x = 1; x <= 10; ++x) {
                                m_stringList.push_back(QString::number(x));
                            }
                            endInsertRows();
                            qDebug() << "insertRows is called.";
                        
                            return true;
                        }
                        

                        As result I get an empty List. On console I can also see that the function is not called. So my question is, how to handle insertRows() function? Did stringList.insert(position, ""); from the Model/View Programming tutorial only reservs an empty line? I thought that there is the entry-point where I have to insert the data.

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by JonB
                        #13

                        @makopo
                        Your insertRows() is called with a position to start the insert from and a number of rows to insert there. But all you do is ignore these and append 10 rows. You need to respect and act on the parameters. (Same btw for deleteRows().) The newly inserted rows should be blank for this call.

                        M 1 Reply Last reply
                        0
                        • JonBJ JonB

                          @makopo
                          Your insertRows() is called with a position to start the insert from and a number of rows to insert there. But all you do is ignore these and append 10 rows. You need to respect and act on the parameters. (Same btw for deleteRows().) The newly inserted rows should be blank for this call.

                          M Offline
                          M Offline
                          makopo
                          wrote on last edited by
                          #14

                          @JonB
                          Thank you. I rewrote the loop as recommended in the Model/View Programming tutorial.

                          beginInsertRows(QModelIndex(), position, position + rows - 1);
                          for (int row = 0; row < rows; ++row) {
                              m_stringList.insert(position, "");
                          }
                          endInsertRows();
                          qDebug() << "insertRows is called.";
                          

                          As I can see on the console insertRows() is not called.

                          JonBJ 1 Reply Last reply
                          0
                          • M makopo

                            @JonB
                            Thank you. I rewrote the loop as recommended in the Model/View Programming tutorial.

                            beginInsertRows(QModelIndex(), position, position + rows - 1);
                            for (int row = 0; row < rows; ++row) {
                                m_stringList.insert(position, "");
                            }
                            endInsertRows();
                            qDebug() << "insertRows is called.";
                            

                            As I can see on the console insertRows() is not called.

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by
                            #15

                            @makopo
                            ? Why/when do you expect it to be called? You have to call it if you wish to insert some rows. (And again for deleteRows().)

                            M 1 Reply Last reply
                            0
                            • JonBJ JonB

                              @makopo
                              ? Why/when do you expect it to be called? You have to call it if you wish to insert some rows. (And again for deleteRows().)

                              M Offline
                              M Offline
                              makopo
                              wrote on last edited by makopo
                              #16

                              @JonB

                              insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) is virtual. I thought it is called automatically?

                              As I understand now m_stringList.insert(position, ""); only reservs an empty row and I have to add data to the table outside the model class?

                              JonBJ 1 Reply Last reply
                              0
                              • M makopo

                                @JonB

                                insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) is virtual. I thought it is called automatically?

                                As I understand now m_stringList.insert(position, ""); only reservs an empty row and I have to add data to the table outside the model class?

                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by
                                #17

                                @makopo
                                The virtual just means that if anything calls QAbstractTableModel::insertRows() --- even if it knows nothing about your derived class --- the implementation code you have written will be called.

                                The outside world will call insertRows() when it wants/needs to. The outside world will do that with no knowledge that you have implemented it via m_stringList.insert(). The outside world will call setData() for the desired column values on newly inserted row(s) after it has called insertRows().

                                M 1 Reply Last reply
                                0
                                • JonBJ JonB

                                  @makopo
                                  The virtual just means that if anything calls QAbstractTableModel::insertRows() --- even if it knows nothing about your derived class --- the implementation code you have written will be called.

                                  The outside world will call insertRows() when it wants/needs to. The outside world will do that with no knowledge that you have implemented it via m_stringList.insert(). The outside world will call setData() for the desired column values on newly inserted row(s) after it has called insertRows().

                                  M Offline
                                  M Offline
                                  makopo
                                  wrote on last edited by makopo
                                  #18

                                  @JonB
                                  That was not clear for me. I did not call the headerData(...) and data(...) function. I only generate a instance of the model class, set the model to the view and get a table. Thought that setData(...) and insertRows(...) works on the same way.

                                  So as I understand from your last post, I have to do something like this:

                                  //QMainClass.cpp
                                  m_tableDataModel->insertRows(0, 1, QModelIndex());
                                  m_tableDataModel->setData(QModelIndex(), QParameterList(), QValueList(), 2); //valuelist is a vector and stores data that should be overwritten in the view
                                  m_tableView->setModel(m_tableDataModel);
                                  

                                  I'am sry. As a beginner the principle of table view is hard to understand.

                                  JonBJ 1 Reply Last reply
                                  0
                                  • M makopo

                                    @JonB
                                    That was not clear for me. I did not call the headerData(...) and data(...) function. I only generate a instance of the model class, set the model to the view and get a table. Thought that setData(...) and insertRows(...) works on the same way.

                                    So as I understand from your last post, I have to do something like this:

                                    //QMainClass.cpp
                                    m_tableDataModel->insertRows(0, 1, QModelIndex());
                                    m_tableDataModel->setData(QModelIndex(), QParameterList(), QValueList(), 2); //valuelist is a vector and stores data that should be overwritten in the view
                                    m_tableView->setModel(m_tableDataModel);
                                    

                                    I'am sry. As a beginner the principle of table view is hard to understand.

                                    JonBJ Offline
                                    JonBJ Offline
                                    JonB
                                    wrote on last edited by JonB
                                    #19

                                    @makopo
                                    Those are the right calls. But you'll have to work a bit on all your parameters to setData(). If you have multiple columns (I don't know if you do) you'll have to call setData() for each one.

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

                                      A QTableView is just a widget showing your model as a table. Nothing more.

                                      From the looks of it, you did not understand that the model is a wrapper on top of your data structure. From what you wrote it's a QStringList. So you have a model with a single column and as many rows as your string list.

                                      The setData method shall be called to modify the data of one element of your data structure.

                                      If you want to initialise your model with a ready made list, add a method for that.

                                      Note that if your data structure is a QStringList you might as well use the QStringListModel class.

                                      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
                                      3
                                      • M Offline
                                        M Offline
                                        makopo
                                        wrote on last edited by makopo
                                        #21

                                        I think I understand the principle of a model. Because of this I didn't understand why in this example an empty string is inserted. I think this little for loop is my problem. Why they insert data here?

                                        bool StringListModel::insertRows(int position, int rows, const QModelIndex &parent)
                                        {
                                            beginInsertRows(QModelIndex(), position, position+rows-1);
                                        
                                            for (int row = 0; row < rows; ++row) {
                                                stringList.insert(position, ""); //empty strings are inserted in every row (inserting data alike)?
                                            }
                                        
                                            endInsertRows();
                                            return true;
                                        }
                                        

                                        In my project I use two columns. Column 0 includes labels and is fixed, so I think I didn't need SetData() for the first column. Column 1 gets values of different types and this values should be constantly updated. For both columns I use a QVector<QString>. To add data to the vector I wrote two functions: QParameterList() and QValueList(). I also implement a function AddData() that has a QVector<QString> type as parameter.

                                        void DataTableModel::AddData(const QVector<QString>& parameter)
                                        {
                                            m_parameter = parameter;
                                        }
                                        

                                        In my QMainClass I call AddData() and with this I generate the first column (column with the fixed values). Now I call the reimplemented SetData() function and insert (only for test purposes) data to one cell. I got an empty cell. I can fill all cells in column 1 manually, I get an empty column. I think this happens because the empty string overrides the value, I inserted with SetData(...)?

                                        QVariant DataTableModel::SetData(const QModelIndex& index, const QVariant& value, int role)
                                        {
                                            if (role == Qt::DisplayRole && index.row() == 0 && index.column() == 1) {
                                                return QString(value.toString());
                                        
                                            }
                                            return QVariant();
                                        }
                                        
                                        // QMainClass.cpp
                                        QVariant value = QString("Test");
                                        m_tableDataModel->InsertRows(QModelIndex(), 0, 3);
                                        m_tableDataModel->AddData(QParameterList());
                                        m_tableDataModel->SetData(QModelIndex(), value, 2);
                                        m_tableView->setModel(m_tableDataModel);
                                        
                                        1 Reply Last reply
                                        0
                                        • SGaistS Offline
                                          SGaistS Offline
                                          SGaist
                                          Lifetime Qt Champion
                                          wrote on last edited by
                                          #22

                                          When you add rows, your data structure should contain something that can be returned to the view. Still in the case of your string list, you shall adjust the size of the list and then put some meaningful default data in the new empty spots. In this case empty strings.

                                          Your SetData method does not make sense. By the way, the correct name is setData. Casing is important.

                                          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