我正在开发一个模拟器。我为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();
}
答案 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();
}