views:

303

answers:

4

I am developing a simulator. I have chosen QT for the GUI. My project involves a lot of manipulation of data and I use QT just to plot my results.

My code structure is such that my main function contains a global object of my data, an object of the QT GUI and other objects for manipulating this data. I need to modify this data at every 30 ms. I have also attached a simplified version of my main file.

My problem is that I cannot call functions of my other objects (other than the GUI) before exiting the QT object. I have implemented timers in QT in isolation which plots the new data and works fine. All I want to do is call my ai and phySim object at a particular time interval independant of the QT object. I want these three objects to be completely independent.

world* _world;
int main(int argc, char *args[])

{
_world = new world();


gui *GUI; ///QT object

ai *AI;//object to manipulate data

phySim *sim;//object to manipulate data

/////////////////////////////////// this gets executed only when i close the QT gui
    AI = new ai(_world); 
AI->doSomething();

sim = new phySim(_world);
sim->updateWorld();
//////////////////////////////////////////////////////////////////////////////

QApplication app(argc,args);
GUI = new gui(_world);  
GUI->show();


return app.exec();  
} 
A: 

Have you tried running the code in a thread (http://qt.nokia.com/doc/4.6/threads.html) ?

kovica
my QT part is already in a threadI want to decentralize my code away from QTI can solve my problem if I keep QT as an entry point and then call my modifiers from there but I want the entry point to be main only
By nature I'm a Java programer and in Java you have to run you GUI code in EDT (Event Dispatch Thread : http://mindprod.com/jgloss/edt.html).
kovica
+1  A: 

Take a look at the Signals and Slots in Qt. Connect a "closed" signal that you emit when you close your GUI to a "startThread" slot. Have your AI and Simulation running in separate threads and if they need to interact, make use of signals/slots again.

You say you want the three objects to be "completely independent" -- then you should give each of them their own thread.

swanson
I know signals and slots and i have implemented my QT function using that only. My AI and simulation will have nothing to do with QT. I am running this code on Ubuntu so wat libraries should I use for creating threads for AI and Simulator ? Should I use boost ?
You can use a native threading library in C++ or you can use the `QThread` that comes with qt
swanson
definitly pthreads, no useless abstraction overhead, if you are going for *nix/posix only.
penguinpower
A: 

Maybe you should try not not run the app.exec(), but instead create a custom (almost) infinite loop, call processEvents() within that loop and your updateWorld() plus a wait of 30ms (or a little less, due to the function execution will take some ms). Drawing is then part of Qt (you should pass the instance of your simulator and add a render method (maybe best in pure OpenGL, as this can be passed through the Qt layer via a QGLWidget). Call that method within paint() or respectivly paintGL() for QGLWidget I hope this helps (a little), you should read QGLWidget doc

Note: You will have to write some wrappers in form of signals, calling your simulationObj methods, otherwise no UI interaction will be possible within Qt.

penguinpower
It is an interesting approach, but I wouldn't usually recommend that people avoid Qt's application execution loop so entirely.
Caleb Huitt - cjhuitt
It's not about avoiding them, it's to do what fits the purpose, and in this case this depends on the target refresh rate.
penguinpower
A: 

I was going to suggest overriding some event methods on QApplication but event loops can be tricky since you have some "child loops" http://labs.trolltech.com/blogs/2010/02/23/unpredictable-exec. In one of the 2009 Tech talks on there is a part that explains this too.

One approach is to separate your GUI a bit more by using a Client Server architecture. Your sim can be the server and Qt GUI the client. There are some nice samples in Qt using sockets.

Another approach is to use QTimer to update (or poll) your Sim. You might not even need threads.

 void SomeGUI::SomeGUI(..)...
 {
   //Init sim
   m_World = new world();
   m_AI = new ai(m_World); 
   m_Sim = new phySim(m_World);

  ...
  //Connect timer
  QTimer *timer = new QTimer(this);
  connect(timer, SIGNAL(timeout()), this, SLOT(updateWorld()));
  timer->start(100); //or whatever interval works
  ...

 }

 void SomeGUI::updateWorld()
 {
   //Update sim state
   m_AI->doSomething();
   m_Sim->updateWorld();
   updateGUI();
 }
Derick
You forgot one viable point: If the time interval gets to small, the UI will leak due to the execution loop being to slow. Manual event processing (via processEvents()) within a loop with a small msleep() will work a _lot_ better. I can tell this from personal experience with OpenGL, signal/slot-concept and threads.Edit: Of course it all depends on the refresh interval which method is usefull. But everything with about 25msec per loopcycle should be done with a custom loop.Correct me if you got othr experiences with that.
penguinpower