PDA

View Full Version : Live Update data in table



abghosh
24th February 2010, 16:59
Hi
I have a table with 1 row initially.
Now when I insert a row in the table, I want to read some specif data into the cells. These values are retrieved using two different nested slots. Also at the same time I want to update the cells continuously as and when the slot retrieve data. I am using timer in a slot to continuosly read data from the source. But how can I update the table contents.


Thanks in advance for any help.


Abhijit

Lykurg
24th February 2010, 17:05
You can update the data e.g. via
QTableWidget *tw = /*...*/
tw->item(0,0)->setText("foo");

abghosh
24th February 2010, 17:49
You can update the data e.g. via
QTableWidget *tw = /*...*/
tw->item(0,0)->setText("foo");

Hi LyKurg

As I told you that I am using two SLOTS which are nested and in one of these SLOTS I am using a timer to retrieve data continuously. Let me explain my problem with the code:


//First Slot
void MainWindow::getData()
{
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(readData(QNetworkReply*)));
QNetworkRequest request;
request.setUrl(QUrl("http://finance.yahoo.com/q?s=GOOG"));
manager->get(request);
}

//2nd Slot
void MainWindow::readData(QNetworkReply *reply){
QByteArray bytes = reply->readAll();
connect(reply, SIGNAL(readyRead()), this, SLOT(repaint()));
QString string = QString::fromUtf8(bytes);
QString Temp1;
Temp1 = string.section("<div class=\"hd\"><h2>", 2, 2);
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(getData()));
timer->start(10000);
}

Now suppose instead of "GOOG" I want to read a string from a cell of the row that I have recently inserted and get Temp1 value to be displayed in the second column. So basically I want to insert a row on the run and insert a value in the first column of the row. After Inserting the value I want the program to run slot 1 and 2 with "GOOG" replaced by the value in column 1 and column 2 giving m the result which will be updated regularly as in Slot 2.

If you have more query pls feel free to ask.
Once again thanks for your help.

Abhijit

Archimedes
24th February 2010, 18:31
If I understood your problem then a stupid solution is to keep a const QString of your initial url ("http://finance.yahoo.com/q?s="), then add a private QString variable that represents the retrieved data to be appended to the initial url.
Create a function that it's purpose is to retrieve the data you want from the table, let it be the 1st thing to be called in the slot getData(). Create a temp QString that will hold the new url and then pass it to the request.

Or the moment you insert the new value to the table create the string with the new url, store it as a private member (let's call it m_finalUrlStr) and then in getData(), request.setUrl(QUrl(m_finalUrlStr));

Lykurg
25th February 2010, 00:42
Hi, the first time I misunderstood you totally. For now, just a quick side note: You are creating a QNetworkAccessManager and QTimer on the heap every time the slots are called without deleting them which will end in a hight memory usage for your program, since they are only deleted after destroying Mainwindow.

abghosh
25th February 2010, 05:55
If I understood your problem then a stupid solution is to keep a const QString of your initial url ("http://finance.yahoo.com/q?s="), then add a private QString variable that represents the retrieved data to be appended to the initial url.
Create a function that it's purpose is to retrieve the data you want from the table, let it be the 1st thing to be called in the slot getData(). Create a temp QString that will hold the new url and then pass it to the request.

Or the moment you insert the new value to the table create the string with the new url, store it as a private member (let's call it m_finalUrlStr) and then in getData(), request.setUrl(QUrl(m_finalUrlStr));

Hi Archimedes

Thanks for your reply. Can you please demonstarate the same with an example?
Actually I am not at all getting the idea about how it will work.

Thanks

Archimedes
25th February 2010, 12:28
Well let's say you are making the new url when you are about to insert the data in the table (you know the value at that time and you don't need to insert it and then retrieve it again). The following code is not tested (compile or run) and just shows the basic idea nothing more.


// header file
MainWindow
{
....
// let's say you want to insert a QString in the table
// cause I'm not sure what you're passing in it
void insertInTable(QString &toInsert);
...
public slots:
void getData();
void readData();
...
private:
QString m_finalUrlStr; // holds the new url
QNetworkAccessManager *manager;
QTimer *timer;
...
}

// cpp file
const QString initialUrlStr = "http://finance.yahoo.com/q?s=";

// Constructor
MainWindow::MainWindow()
{
// initialize m_finalUrlStr to the 1st url you want to send a request
m_finalUrlStr = "http://finance.yahoo.com/q?s=GOOG";
// putting the mem allocation and the connections here, Lykurg described why
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(readData(QNetworkReply*)));
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(getData()));
...
}

void MainWindow::insertInTable(QString &toInsert)
{
m_finalUrlStr.clear(); // clear the previous url
m_finalUrlStr = initialUrlStr;
m_finalUrlStr += toInsert; // you got the new url
...// code that does the insertion in the table
}

//1st Slot
void MainWindow::getData()
{
QNetworkRequest request;
request.setUrl(QUrl(m_finalUrlStr ));
manager->get(request);
}

//2nd Slot
void MainWindow::readData(QNetworkReply *reply){
QByteArray bytes = reply->readAll();
connect(reply, SIGNAL(readyRead()), this, SLOT(repaint()));
QString string = QString::fromUtf8(bytes);
QString Temp1 = string.section("<div class=\"hd\"><h2>", 2, 2);
insertInTable(Temp1); // I assume that Temp1 holds the data you want to insert
// in the table, I'm just guessing actually
timer->start(10000);
}


If the insertion in the table is done by the user and it's not a result of the reply (that I assumed here) then simply remove the call of insertInTable in the 2nd slot and do the string manipulations in the function (probably a slot) that does the insertion.
Anyway, I hope the above sample will give you an idea of how to do this task :p

abghosh
25th February 2010, 16:45
Thanks Archemedis,
But suppose I have two rows in the table & I want to update the 2nd column of both the rows. How ill that work??

Archimedes
25th February 2010, 18:16
You can update the data e.g. via
QTableWidget *tw = /*...*/
tw->item(0,0)->setText("foo");

QTableWidgetItem * QTableWidget::item ( int row, int column ) is the function, so simply put the row and the column you want.

Also Qt is the best documented API out there with a great tool (Qt Assistant). So use that to your advantage, you'll find a lot of answers there! Anyway, read the following starting with QTableWidget (http://doc.qt.nokia.com/4.6/qtablewidget.html), QTableWidgetItem (http://doc.qt.nokia.com/4.6/qtablewidgetitem.html) and for a complete explanation of the Model/View read this Model/View Programming (http://doc.qt.nokia.com/4.6/model-view-programming.html).