Show live data into a table
-
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?
-
Hi,
Using the model/view paradigm will do that automatically for you. Just set the value on the model and it will trigger the update of the table view.
-
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?
@makopo
For best results, you should derive fromQAbstractTableModelto create your own model. Then bind aQTableViewto 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
QStandardItemModelfor your data instead of your ownQAbstractTableModel, or even aQTableWidgetto wrap the model + view into one. You might start out with these if you are a beginner, and maybe upgrade to aQAbstractTableModel/QTableViewwhen you are ready for better performance/typing. -
Hi there,
is there a functionality to add a
QTableViewto aGridLayout?I create aQTableViewsuccessfully with the following lines but this (logically) creates a new window.m_tableView->setModel(m_tableDataModel); m_tableView->show(); -
@makopo
What is aGridLayout? If you meanQGridLayout, that is aQLayout.QTableViewis aQWidget. You can always add aQWidgetto aQLayout. -
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
-
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 makeQTableVieweditable, but I think that this is not the right way for my requirement.I implement the virtual
datafunction 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
QVectortypes 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? -
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 makeQTableVieweditable, but I think that this is not the right way for my requirement.I implement the virtual
datafunction 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
QVectortypes 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?@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
intand changed it, the result'd be the same. To add to the model define youraddRowor 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,endInsertRowsand so on. -
On addition to @kshegunov you also need to re-implement setData so that you can properly notify when data changes.
-
I did not understand how to implement
insertRows()correctly and it also looks like that the function is not called. Because theQAbstractTableModeldid not work, I rebuild the Qt tutorial which uses theQAbstractListModel.In
insertRows()I callbeginInsertRows(), than I run the loop and than I callendInsertRows().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. -
I did not understand how to implement
insertRows()correctly and it also looks like that the function is not called. Because theQAbstractTableModeldid not work, I rebuild the Qt tutorial which uses theQAbstractListModel.In
insertRows()I callbeginInsertRows(), than I run the loop and than I callendInsertRows().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.@makopo
YourinsertRows()is called with apositionto start the insert from and a number ofrowsto insert there. But all you do is ignore these and append 10 rows. You need to respect and act on the parameters. (Same btw fordeleteRows().) The newly inserted rows should be blank for this call. -
@makopo
YourinsertRows()is called with apositionto start the insert from and a number ofrowsto insert there. But all you do is ignore these and append 10 rows. You need to respect and act on the parameters. (Same btw fordeleteRows().) The newly inserted rows should be blank for this call.@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. -
@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. -
@makopo
? Why/when do you expect it to be called? You have to call it if you wish to insert some rows. (And again fordeleteRows().)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? -
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?@makopo
Thevirtualjust means that if anything callsQAbstractTableModel::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 viam_stringList.insert(). The outside world will callsetData()for the desired column values on newly inserted row(s) after it has calledinsertRows(). -
@makopo
Thevirtualjust means that if anything callsQAbstractTableModel::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 viam_stringList.insert(). The outside world will callsetData()for the desired column values on newly inserted row(s) after it has calledinsertRows().@JonB
That was not clear for me. I did not call theheaderData(...)anddata(...)function. I only generate a instance of the model class, set the model to the view and get a table. Thought thatsetData(...)andinsertRows(...)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.
-
@JonB
That was not clear for me. I did not call theheaderData(...)anddata(...)function. I only generate a instance of the model class, set the model to the view and get a table. Thought thatsetData(...)andinsertRows(...)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.
-
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.