PDA

View Full Version : Refresh QDataTable



shamik
24th November 2006, 10:43
hii friends

i have a QDataTable widget in the dialog that contains data from mysql database.
now when the dialog gets loaded i want that the data table should show the changes immediately if the database gets changed. i.e. data table should update itself around every (for example) 3secs.

i have tried out calling the method "refresh()" like this : dataTable1->refresh()
(dataTable1 is the name which i have given to this QDataTable widget in the dialog.)

it dint worked.
i am editing the code in kdevelop and from there also i tried calling the function "update()"
but the error says " update undeclared ".

the code which i have got has got this function "update()" to refresh the table and there it is working. but in my code it is not. i have included the header files pthread.h and unistd.h (i donno wheather it has got anything to do with it or not).

please tell me how to refresh this qdatatable.

thanks and regards.
shamik

jacek
24th November 2006, 10:50
From where did you invoke refresh()?

shamik
24th November 2006, 11:40
refresh is invoked from the thread created from within main function
then main loads a dialog which again loads another dialog which contains the QDataTable. and i want to refresh this QDataTable.


regards
shamik

jacek
24th November 2006, 14:56
refresh is invoked from the thread created from within main function
It won't work this way. Read this carefully: http://doc.trolltech.com/3.3/threads.html

Actually you don't need a whole thread just to invoke refresh() every 3 seconds --- you can use QTimer instead.

ederbs
25th November 2006, 23:11
Use Qtimer,

QTimer *timer = new QTimer( this );
connect( timer, SIGNAL(timeout()), SLOT(refreshTable()) );
timer->start( 3000, FALSE ); /* 3 seconds single-shot timer 3000 */

void MainForm::refreshTable()
{
dataTable->refresh(QDataTable::RefreshData);
}

shamik
27th November 2006, 04:31
thanks for the code and the suggestion friends,

but i dont wanna use qtimer and qthreads. i only want to use pthreads. there are few gui and i think if one gets terminated then the qtimer will stop working (i dont know 4 sure but i'll try).

but please tell me how to do it using pthreads.

shamik

jacek
27th November 2006, 16:10
ti think if one gets terminated then the qtimer will stop working (i dont know 4 sure but i'll try).
No, it won't stop unless you destroy it or block the event loop.


please tell me how to do it using pthreads.
You will have to use custom events (http://doc.trolltech.com/3.3/qcustomevent.html) to notify the GUI that it has to refresh itself and of course the effect will be exactly the same as if you were using QTimer.

shamik
28th November 2006, 03:49
i have tried out wit the QTimer.
the timer is getting executed but the QDataTable is not getting updated i.e. refreshed.
i set the timer of 3 secs . and the only work it had to do was to print a value and refresh the table.
it was printing the value correctly every 3secs but never refreshed the table.
i have made another project file through which i make changes in the mysql database and that changes should get reflected in this project when the timer runs. but it is still not getting refreshed or updated.

the function which i tried are : dataTable->refresh(QDataTable::RefreshData);
dataTable->refresh();

none of these worked.

please tell me what to do with it. in the project which i have got as a sample, update() is used to refresh the table. the only difference between that and the one which i have made is in that project QTable is used and i am using QDataTable.
but whenever i write update() function then the compiler immediately gives update() undeclared.

now wat ?? is there any solution?

shamik

sunil.thaha
28th November 2006, 08:08
Could you please provide a minimum compilable example ?

shamik
28th November 2006, 09:12
main.cpp is as under :


#include <qapplication.h>
#include "loginfrm.h"
#include "editfrm.h"
#include<qsqldatabase.h>
#include<qstring.h>
#include <qthread.h>
#include <stdlib.h>
#include <qwidget.h>
#include <qtimer.h>

int main( int argc, char **argv )
{
QApplication a( argc, argv );
QSqlDatabase *db = QSqlDatabase::addDatabase("QMYSQL3");
db->setDatabaseName("logindb");
db->setUserName("root");
db->setPassword("");
db->setHostName("localhost");
db->open();
if ( !db->open())
{
qWarning(" database connection no thayu ");
}

editfrm efrm;

a.setMainWidget( &efrm );

efrm.show();
qWarning("waiting for login");
qWarning("creating timer");
QTimer *timer = new QTimer( &efrm , "mt" );
efrm.connect( timer, SIGNAL(timeout()), SLOT(refreshTable()) );
timer->start( 5000, FALSE ); /* 3 seconds single-shot timer 3000 */
a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );

qWarning("Leaving main");
return a.exec();

}

NOTE : the editfrm gets some of its values from loginfrm because it is loaded first. but for the ease of understanding i have directly called editfrm from the main. It might be incorrect from the implementation point of view but it is absolutely correct logically. The loginfrm does nothing but initializes some global variables so that editfrm can use it. In the actual code the loginfrm is loaded first and then if the login is correct then the editfrm is loaded. It is only here that i have changed main function to show() the editfrm directly.

editfrm.ui.h is as follows :


#include<qapplication.h>
#include<qsqldatabase.h>
#include "loginfrm.h"
#include "modifyfrm.h"
#include <qwidget.h>
#include<qdatatable.h>
#include <qtimer.h>
#include<qthread.h>
#include <qobject.h>
#include <qtable.h>
#include <qsqlcursor.h>

static int btn;
static int i=0;

void editfrm::initvalues()
{

loginfrm *lfrm = new loginfrm();

if ( lfrm->check())
{
PB_add->setEnabled(TRUE);
PB_edit->setEnabled(TRUE);
PB_delete->setEnabled(TRUE);
}
else
{
PB_add->setEnabled(FALSE);
PB_edit->setEnabled(FALSE);
PB_delete->setEnabled(FALSE);
}

}


void editfrm::addclicked()
{
btn=1;
modifyfrm *mfrm = new modifyfrm();
mfrm->initvalues();
hide();
mfrm->show();
}


void editfrm::editclicked()
{

btn=2;
modifyfrm *mfrm = new modifyfrm();
mfrm->initvalues();
hide();
mfrm->show();
}


void editfrm::deleteclicked()
{
btn=3;
modifyfrm *mfrm = new modifyfrm();
mfrm->initvalues();
hide();
mfrm->show();
}

int editfrm::checkbtn()
{
return btn;
}

void editfrm::cancelclicked()
{
loginfrm *lfrm = new loginfrm(this);
hide();
lfrm->show();
}

void editfrm::refreshTable()
{
QString swar="";
swar.sprintf("tick tick %d",i);
qWarning(swar);
dataTable1->update();
dataTable1->repaint(true);
dataTable1->refresh(QDataTable::RefreshAll);
update();
i++;
}

as per the timer after every 3 secs "tick tick i " is printed but the datatable is not getting updated or refreshed.
as u can see i have tried out with update(), repaint(), refresh(), none of which is working here. the datatable is failing to show the updated database. The database is getting updated from another GUI which is out of this project. I simultaneously run both the project 's GUI and after making changes in the database from one GUI in one project it doesnt get showed in the GUI of another project.

i hope atleast now the picture is very much clear.
please help me solve this problem

thanks and regards
shamik

jacek
28th November 2006, 10:25
I simultaneously run both the project 's GUI and after making changes in the database from one GUI in one project it doesnt get showed in the GUI of another project.
Can you see those changes if you connect to the database using a SQL console?

shamik
28th November 2006, 12:05
Can you see those changes if you connect to the database using a SQL console?

what do you mean by this SQL console? how to start it??

jacek
28th November 2006, 12:14
what do you mean by this SQL console? how to start it??
It's a program that allows you to issue SQL queries to the database server. AFAIR MySQL calls it "mysql".

shamik
28th November 2006, 12:41
i opened the console and typed mysql
then mysql prompt appeared. do you mean this as mysql console??

now i typed the select query on that particular table. now the table is shown on the console.
keeping that open, i ran the exe of the project through which i want to change the database content. i made the changes from its GUI. but the sql table in the console showed the same result (it is obvious). to see the changes i have to write the query in the console again. then i can see the changes.

this is the case with the original project too. the qdatatable widget doesnt reflect the changes as it should be. but whenever i hide it and show other dialog and then again i hide the second dialog and show the original dialog with qdatatable widget then i can see the changes. (hiding and showing is implemented with the help of necessary functions inside the code like show(), hide() ).


if u call opening mysql from console which gives u mysql prompt like this-->
mysql>

then it is obvious that it wil show the changes in the database only if u write the query again after changing it from the GUI.

if u r talking of any other MYSQL console then please tell me how to open it and how to work on it. i'll try on that also.

jacek
28th November 2006, 12:52
but whenever i hide it and show other dialog and then again i hide the second dialog and show the original dialog with qdatatable widget then i can see the changes. (hiding and showing is implemented with the help of necessary functions inside the code like show(), hide() ).
Can you see the changes if you keep that QDataTable shown for more than 5 seconds (i.e. long enough for the timer to emit the signal)?

shamik
28th November 2006, 13:10
no.

no changes are seen in the qdatatable no matter howlong i keep the timer going on

sunil.thaha
28th November 2006, 13:54
It might be possible that the changes you make to the database from the client are not commited !!:confused:

So, You can try comitting the changes to database.
One more thing, Hope you are setting the interval as 3000 for 3 Sec

shamik
29th November 2006, 04:51
i have treid commiting the database after every record change but still it isnt working. the timer time can b anything, may be 3, 5, 7 sec etc. that is not a problem.
after the database is changed the timer may go on to even ticking 40 times still there is no change in the QDataTable.

even if the QDataTable is kept shown for say 5 mins then also there is no change in it. i.e. the updated values are not shown.

is there anything that v m missing ? i donno why does this simple one takes too much of time.
please help me

jacek
29th November 2006, 18:27
Can you see the changes if you update your database using the console (i.e. "mysql" program)?

shamik
30th November 2006, 05:04
No
cant see the changes in the QDataTable even if i change the database from mysql prompt :
mysql>

i dont understand what is the problems.??

jacek
30th November 2006, 09:01
Do you start any transactions before reading data from the database?

shamik
30th November 2006, 10:21
i dont use any trasactions
just start mysql and start reading data or execute the exe which does the same.

no complex things are done with mysql. just reading and writing the data. no transactions are used. no committing is done either.

this i think is an exceptional case of mine.

jacek
30th November 2006, 10:42
What happens if you set a new cursor instead of invoking refresh()?

shamik
30th November 2006, 11:59
i have temporarily solved the problem

what i used to do is i was loading a login dioalog from main. then from login dialog i used to load the edit dialog which contained the QDataTable and hide the login dialog.
but now what i m doing is instead of loading the login dialog from main, i m directly loading the edit dialog which contains QDataTable. now i can easily see the changes made to the database either from mysql prompt or from another project's GUI in current QDataTable without unloading and loading. i.e. now the refresh() and update() functions are working fine.

i think this is not the optimum solution but still it satisfies my requirements.

anyways,
thanks allllllloooooooot to all of you who have helped me so far and contributed in solving my problem.

but the original problem is still as it is.

hope the posts will continue in this thread so that the problem may not be risen by somebody else.

remember : together we can and we will make the difference. :)

jacek
30th November 2006, 20:51
what i used to do is i was loading a login dioalog from main. then from login dialog i used to load the edit dialog which contained the QDataTable and hide the login dialog.
In other words you had something like this?

int main(...) {
QApplication app(...);
...
LoginDialog dialog; // modal dialog
dialog.exec(); // dialog shows the main window and exec() returns when user closes that window
...
return app.exec();
}

shamik
1st December 2006, 05:04
not exactly like that but somewhat similar.

my main.cpp is already there in the previous page. editfrm is the dialog that contains the QDataTable which gets loaded after loading the login dialog called loginfrm..

from main i used to do the following :

QApplication a(argc,argv);
loginfrm lfrm;
a.setMainWidget(&lfrm);
lfrm.show();
a.connect(......);
return a.exec();

( note that the main in the previous page directly loads editfrm. this i have written only for the ease of understanding. but original main is the one like above)
and from the loginfrm after satisfying the conditions of login name and password i used to do the following :

editfrm *efrm = new editfrm(this);
hide();
efrm.show();

this would hide the login dialog form and show the editfrm dialog which contains the QDataTable.
but unfortunately the datatable is not getting updated.


got the picture clear in the mind??