[Solved] QTableView item update Automatically???
-
There is a thread running! it receives data from internet two times per second, then I set the data in qtablewidget? How can I make the QTableWidget update itselt? now I must click the interface if I want to update the display!
///there is the thread receiving data
DWORD WINAPI MyThreadProc1(LPVOID lpParameter)
{int data=receive(); w.setVal(data); return 0;
}
//////
void TradeSystem::setValue(int num){
QTableWidgetItem *item = new QTableWidgetItem(QString::number(num,10,1));
item->setBackgroundColor(QColor(0,60,10));
ui.tableWidget_3->item(0,0)->setText(QString::number(num,10,0));}
help!!!!!
-
Relax, mate. Are you sure you are sending the data you receive from the thread to the table widget? Are you sure the even loop has the time to pass the data?
Qt's MVC views will update automatically to any changes made to the Model class. So if you use QTableView instead of QTableWidget, and supply a proper model, it will work fine.
-
@sierdzio said:
ime to pass the data?
thank you for your answer, buddy! The data has been send to the interface and I am sure the tablewidget's content has been changed (the content will change if I click the window)!
I don't know why it can not update automatically? and I will change my code to use tableview if I must! -
@tdz09 said:
QTableWidgetItem *item = new QTableWidgetItem(QString::number(num,10,1));
item->setBackgroundColor(QColor(0,60,10));
ui.tableWidget_3->item(0,0)->setText(QString::number(num,10,0));Are you saing that your table is not being updated after you run this?
First, this has a problem: you create a new item in the first line, but you never add it to the QTableWidget. You should call setItem() on your table widget somewhere.
Now, about updating. Even in QTableWidget, the update should happen (close to) immediately. The fact that you need to click for the view to update hints that something may be stealing focus from the widget, and doing some expensive operations in the background. Perhaps your thread is not really a separate thread, and is blocking the UI operations?
-
@sierdzio
Hi buddy!
I have change the code as below:
QTableWidgetItem *item = new QTableWidgetItem(QString::number(num,10,1));
item->setBackgroundColor(QColor(0,60,10));
//ui.tableWidget_3->item(0,0)->setText(QString::number(num,10,0));
ui.tableWidget_3->setItem(0,0,item);
Sorry that it does not work either. I don't know why! there is only one thread and I change the thread to verify whether the thread block the UI operations as follow , but i seems not that!
DWORD WINAPI MyThreadProc1(LPVOID lpParameter)
{
for(int j=0;j<=1000;j++){
w->setValue(j);
Sleep(500);
}
return 0;
}
I dont know why? -
@sierdzio
Then I tried to use tableview and I find it does not change at all.
void TradeSystem::setValue(int num){
QStandardItem *itemID = new QStandardItem(QString::number(num,10,0));//QString::number(j)));
model->setItem(1,1,itemID);
ui.tableView->setModel(model);
}I really do not know what to do!!
-
@tdz09 said:
void TradeSystem::setValue(int num){
QStandardItem *itemID = new QStandardItem(QString::number(num,10,0));//QString::number(j)));
model->setItem(1,1,itemID);
ui.tableView->setModel(model);
}This is not how you should do it. Changing From QWidget to QView is a much bigger operation and involves a lot of code writing. Let's focus on QTableWidget for now - I proposed QTableView when I thought your problem is a little bit different.
I do not know how your thread is working exactly, and how it is connected with your code. I suspect this is the root cause of your problem. Maybe try removing the thread and doing everything in the Qt app - just for test, to see whether the table widget will update as desired.
-
@sierdzio
Yes buddy! Now all the things are done in QT app.
this is a very simple project:
--------------------------------------------main.cpp:
#include "tradesystem.h"
#include <qdebug.h>
#include <QtWidgets/QApplication>
#include "FMdSpi.h"
#include "CalcMod.h"
#include "SMdSpi.h"
#include <windows.h>
#include<cstdlib>
TradeSystem* w;
DWORD WINAPI MyThreadProc1(LPVOID lpParameter)
{
for(int j=0;j<=1000;j++){
w->setValue(j);
Sleep(500);
}
return 0;
}
int main(int argc, char argv[])
{
QApplication a(argc, argv);
CalcMod cm=new CalcMod();
w=new TradeSystem(cm);
HANDLE handle1;
handle1 = CreateThread(NULL,0,MyThreadProc1,NULL,0,NULL);
w->show();
return a.exec();
}
-----------------------------------------interface class: tradesystem.cpp and h file are very simple
TradeSystem::TradeSystem(CalcMod* cm,QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
ui.tableView->setModel(model);
}
void TradeSystem::setValue(int num){
QStandardItem *itemID = new QStandardItem(QString::number(num,10,0));//QString::number(j)));
model->setItem(1,1,itemID);
ui.tableView->model()->setData(ui.tableView->model()->index(1 ,1),num);
}It is very simple.......
-
I think in such case, using WinAPI threads is completely superfluous. Use QThread instead. It will also have a benefit of working on other platforms out of the box.
You are changing the w object from a different thread, and creating a new UI items from a different thread. Qt does not support that. UI elements should all be created in the same thread. Your data thread should send messages, signals, or setting some data (while locking a mutex, of course), and then the UI should pick it up on it's side.
-
Yes buddy, you are right! as you say "You are changing the w object from a different thread, and creating a new UI items from a different thread. Qt does not support that". after making setValue a slot, problems solved!
thank you for your help!! my friend
-
Ha, that is good to hear. Happy coding!