如何使用QT运行并行代码?

时间:2010-02-23 22:19:42

标签: multithreading qt simulator

我正在开发一个模拟器。我为GUI选择了QT。我的项目涉及大量的数据操作,我使用QT来绘制我的结果。

我的代码结构是这样的,我的main函数包含我的数据的全局对象,QT GUI的对象和用于操作此数据的其他对象。我需要每30毫秒修改一次这个数据。我还附上了我的主文件的简化版本。

我的问题是在退出QT对象之前我无法调用其他对象(GUI除外)的函数。我已经在QT中实现了定时器,它们绘制了新数据并且工作正常。我想做的就是以独立于QT对象的特定时间间隔调用我的ai和phySim对象。我希望这三个对象完全独立。

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();  
} 

3 个答案:

答案 0 :(得分:2)

看看Qt中的Signals and Slots。将关闭GUI时发出的“关闭”信号连接到“startThread”插槽。让您的AI和Simulation在不同的线程中运行,如果需要进行交互,请再次使用信号/插槽。

你说你希望这三个对象“完全独立” - 那么你应该给每个对象都有自己的线程。

答案 1 :(得分:0)

也许您应该尝试不要运行app.exec(),而是创建一个自定义(几乎)无限循环,在该循环中调用processEvents()并且updateWorld()加上等待30ms(或者少一点,由于函数执行将花费一些ms)。然后绘图是Qt的一部分(你应该传递模拟器的实例并添加一个渲染方法(也许最好用纯OpenGL,因为它可以通过QGLWidget传递到Qt层)。在paint()中调用该方法或者相应地paintGL()对于QGLWidget我希望这有所帮助(一点点),你应该阅读QGLWidget doc

注意:您必须以信号的形式编写一些包装器,调用simulationObj方法,否则在Qt中不可能进行UI交互。

答案 2 :(得分:0)

我打算建议覆盖QApplication上的一些事件方法,但事件循环可能很棘手,因为你有一些“子循环”http://labs.trolltech.com/blogs/2010/02/23/unpredictable-exec。在2009年的一次技术谈判中,有一部分也解释了这一点。

一种方法是使用客户端服务器体系结构将GUI分开一些。您的SIM可以是服务器,Qt GUI是客户端。 Qt中有一些使用套接字的好样本。

另一种方法是使用QTimer更新(或轮询)您的Sim。你可能甚至不需要线程。

 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();
 }