题
我正在开发一个模拟器。我选择 QT 作为 GUI。我的项目涉及大量数据操作,我使用 QT 只是为了绘制结果。
我的代码结构是这样的,我的主函数包含我的数据的全局对象、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();
}
解决方案
也许你应该尝试不运行 app.exec()
, ,而是创建一个自定义(几乎)无限循环,调用 processEvents()
在那个循环和你的 updateWorld()
再加上 30 毫秒的等待(或少一点,因为函数执行将花费一些毫秒)。那么绘图就是 Qt 的一部分(您应该传递模拟器的实例并添加渲染方法(也许在纯 OpenGL 中最好,因为这可以通过 QGLWidget 传递到 Qt 层)。在内部调用该方法 paint()
或分别 paintGL()
对于 QGLWidget 我希望这有帮助(一点),你应该阅读 QGLWidget 文档
笔记:您必须以信号的形式编写一些包装器,调用您的simulationObj 方法,否则Qt 中将无法进行UI 交互。
其他提示
看看 信号和槽 在 Qt 中。将关闭 GUI 时发出的“关闭”信号连接到“startThread”槽。让您的 AI 和模拟在单独的线程中运行,如果它们需要交互,请再次使用信号/槽。
您说您希望这三个对象“完全独立”——那么您应该为每个对象提供自己的线程。
我打算建议重写 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();
}