PDA

View Full Version : separate class using an interface



qt_gotcha
18th February 2010, 23:35
A very basic question! I am porting a program from Borland builder. This is the setup: a ui interface with a button and a label. A separate clas that is a mathematical model called TWorld, doing a number of calculations. The ui is a class generated in the Eclipse IDE, the main function looks like:

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
mod3 w;
w.show();
return a.exec();
}

where mod3 is a QWidget. Eclipse generates the necessary ui related files. The class TWorld is declared in the class mod3 as:

...
public:
TWorld *W;
...

If the button is pushed the mathmodel class is created and calculations are executed:

void mod3:: on_pushButton_clicked()
{
W = new TWorld();
W->docalc();
}

at the end of the calculations the result should be displayed as the label text on the interface:

void TWorld::docalc()
{
... lots of calculations ...
w.label->setNum(result); //doesn't work
}

this doesn't work of course because label is not part of W (TWorld) but of the interface mod3. mod3 is defined and created in the main function as "w" and only exists there it seems to me. If I make w a global variable, defined as extern in a header file with the definition in main.cpp, I get the error "QWidget: Must construct a QApplication before a QPaintDevice"
I don't understand how I can make the class TWorld "see" the interface. Probably something very simple I am overloocking!
thanks!

qt_gotcha
19th February 2010, 00:25
hmm, apparently it works when w is defined as a pointer in main.cpp:

mod3 *w;

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
w = new mod3();
w->show();
return a.exec();
}

and extern mod3 *w in a header file ?

ChrisW67
20th February 2010, 22:42
You might be looking at this the wrong way around.

If you give TWorld a public getter function to retrieve the result value then the

void mod3:: on_pushButton_clicked()
{
W = new TWorld();
W->docalc();
}
becomes


void mod3:: on_pushButton_clicked()
{
W = new TWorld();
W->docalc();
label.setNum(W->getResultValue());
}
You could also achieve this by having the result value returned by

int TWorld::docalc() {
... do lots of funky stuff
return result;
}
and

void mod3:: on_pushButton_clicked()
{
W = new TWorld();
label.setNum( W->docalc() );
}
You might also want to think about where W is created: Every time this button is pressed a new TWorld will be created... where is the old one deleted?

qt_gotcha
23rd February 2010, 08:57
thanks for the reply. World is deleted at the end of the run, I didn't show. In docalc many loops are performed and the result of each loop should be shown on the interface, not just at the end. Sory for not being clear. Following your example I have to program the calculations (the content of the socalc function) not in a separate class World but as part of the interface class mod3. Is that the only way?

The loops can be long and in the mean time I don't want it to block the interface, so I can also make it a thread.

pitonyak
23rd February 2010, 15:50
My concern is that it sounds like the calculation may take a lot of time. If this is so, perhaps you should perform the calculation in another thread. If you do this, then you can add a signal to report the result of the calculation, and a slot to receive the result of the calculation. Just a thought....

qt_gotcha
3rd March 2010, 18:48
yuo're absolutely right. I did that and it works fine now
thanks
I followed this
http://thesmithfam.org/blog/2009/09/30/lock-free-multi-threading-in-qt/

schnitzel
3rd March 2010, 20:07
yuo're absolutely right. I did that and it works fine now
thanks
I followed this
http://thesmithfam.org/blog/2009/09/30/lock-free-multi-threading-in-qt/

you could have used QProgressDialog, less hassle than multithreading

pitonyak
3rd March 2010, 22:54
Thanks for the link, very informative...