Как запустить параллельные коды, используя QT? - PullRequest
1 голос
/ 24 февраля 2010

Я занимаюсь разработкой симулятора. Я выбрал QT для графического интерфейса. Мой проект включает в себя много манипуляций с данными, и я использую QT только для отображения своих результатов.

Моя структура кода такова, что моя основная функция содержит глобальный объект моих данных, объект графического интерфейса пользователя QT и другие объекты для манипулирования этими данными. Мне нужно изменять эти данные каждые 30 мс. Я также приложил упрощенную версию моего основного файла.

Моя проблема в том, что я не могу вызывать функции других своих объектов (кроме GUI) до выхода из объекта QT. Я реализовал таймеры в QT изолированно, который отображает новые данные и работает нормально. Все, что я хочу сделать, это вызвать мои объекты ai и phySim в определенный интервал времени, независимый от объекта QT. Я хочу, чтобы эти три объекта были полностью независимыми.

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 ]

2 голосов
/ 24 февраля 2010

Посмотрите на Сигналы и слоты в Qt. Подключите «закрытый» сигнал, который вы излучаете при закрытии графического интерфейса пользователя, в слот «startThread». Ваш ИИ и Симуляторы должны работать в разных потоках, и если им нужно взаимодействовать, снова используйте сигналы / слоты.

Вы говорите, что хотите, чтобы три объекта были "полностью независимыми" - тогда вы должны дать каждому из них собственный поток.

0 голосов
/ 24 февраля 2010

Я собирался предложить переопределить некоторые методы событий в QApplication, но циклы событий могут быть сложными, так как у вас есть некоторые «дочерние циклы» http://labs.trolltech.com/blogs/2010/02/23/unpredictable-exec. В одном из технических обсуждений 2009 года есть часть, которая объясняет это .

Один из подходов состоит в том, чтобы немного больше отделить ваш графический интерфейс с помощью архитектуры клиент-сервер. Ваш сим может быть сервером и Qt GUI клиентом. В Qt есть несколько хороших примеров использования сокетов.

Другой подход - использовать QTimer для обновления (или опроса) вашего сима. Возможно, вам даже не нужны темы.

 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();
 }
0 голосов
/ 24 февраля 2010

Возможно, вам следует попытаться не запускать app.exec(), а вместо этого создать собственный (почти) бесконечный цикл, вызвать processEvents() в этом цикле и ваш updateWorld() плюс ожидание 30 мс (или чуть меньше, из-за на выполнение функции уйдет несколько мс). Затем рисование является частью Qt (вы должны передать экземпляр вашего симулятора и добавить метод рендеринга (возможно, лучше всего в чистом OpenGL, так как это можно передать через слой Qt через QGLWidget). Вызовите этот метод в paint() или соответственно paintGL() для QGLWidget Надеюсь, это поможет (немного), вы должны прочитать QGLWidget doc

Примечание: вам нужно будет написать некоторые обертки в форме сигналов, вызывая ваши методы SimulationObj, иначе взаимодействие с пользовательским интерфейсом будет невозможно в Qt.

...