Updating QTablWidget correctly
-
Hi,
I am using a QTableWidget with 2 columns and 3 rows in my GUI. This table is updated approximately 5 times per second. For updating the QTableWidget I have the following function, which takes a QMap as an argument which in turn contains the data to be printed in the QTableWidget. It is called in a slot:
void Ui::updateTable(QMap<QString, float> data) { ui->table->setItem(0,0, new QTableWidgetItem(QString::number(data["a"]))); ui->table->setItem(1,0, new QTableWidgetItem(QString::number(data["b"]))); ui->table->setItem(2,0, new QTableWidgetItem(QString::number(data["c"]))); ui->table->setItem(0,1, new QTableWidgetItem(QString::number(data["d"]))); ui->table->setItem(1,1, new QTableWidgetItem(QString::number(data["e"]))); ui->table->setItem(2,1, new QTableWidgetItem(QString::number(data["f"]))); }
Is that correct? I have a strange feeling, especially since this "new QTableWidgetItem" is called every time - so there are no memory problems (leak), right?
Or would this be the correct way:
void Ui::updateTable(QMap<QString, float> data) { ui->table->item(0,0)->setText(QString::number(data["a"])); ui->table->item(1,0)->setText(QString::number(data["b"])); ui->table->item(2,0)->setText(QString::number(data["c"])); ui->table->item(0,1)->setText(QString::number(data["d"])); ui->table->item(1,1)->setText(QString::number(data["e"])); ui->table->item(2,1)->setText(QString::number(data["f"])); }
Thank you!
-
Hi,
The second solution is cleaner. You are needlessly creating and destroying objects with the first approach.
The setItem documentation states that the widget takes ownership of the item so it should dispose of it properly.
-
@SGaist said in Updating QTablWidget correctly:
Hi,
The second solution is cleaner. You are needlessly creating and destroying objects with the first approach.
The setItem documentation states that the widget takes ownership of the item so it should dispose of it properly.
This makes sense, thank you!
@JonB said in Updating QTablWidget correctly:
I would have thought
void Ui::updateTable(const QMap<QString, float> &data)
would be better?
Why? Would that make a big difference?
-
@TUStudi
Hi
The & means by reference sovoid Ui::updateTable(QMap<QString, float> data)
This will make a copy of the original container you use with it.
If it has many items, that can be expensive.
But QMap uses sharing
https://doc.qt.io/qt-5/implicit-sharing.html
So its cheap to copy.
But for other containers, it can make a huge difference.
Also if it contains complex objects.void Ui::updateTable(const QMap<QString, float> &data)
This does not make a copy but is a reference (like pointer) to the original
map. So very fast. -
@mrjj Thank you very much, I completely ignored that.
One more thing:
In my previous version of updating the table
ui->table->setItem(0,0, new QTableWidgetItem(QString::number(data["a"])));
,
I used a reset button, which callsui->table->clearContent
.
With the new code
ui->table->item(0,0)->setText(QString::number(data["a"]));
, when I click the reset button and then start the updateData-Slot egain, there is a access-violation exception pointing to my first lineui->table->item(0,0)->setText(QString::number(data["a"]));
When I comment out
ui->table->clearContent
, the exception does not occur. What's the issue here? -
@JonB said in Updating QTablWidget correctly:
@TUStudi
When you create a newQTableWidget
, or callclearContents()
, there are no items in the table! Soui->table->item(0,0)
isnullptr
.Ahhh, okay. So actually I do not have to call clearContents, so I will just remove this line of code!
Thanks again =D