Научная визуализация с OpenGL и Qt
-
06-07-2019 - |
Вопрос
Я пытаюсь написать программу визуализации OpenGL для некоторых научных данных с использованием Qt. Я хотел бы иметь возможность использовать мою существующую программу без изменений и просто вызывать glwidget и сообщать ему об обновлении данных в конце каждого временного шага. Однако, чтобы запустить программу Qt, вам нужно использовать QApplication
, а затем qt.run ()
, который блокирует процессор. Р>
Вот псевдокод
main()
{
..set up stuff
myVisualizer = new myGLWidget();
for(int i=0;i<1000;i++)
{
..do calculations
myVisualizer.update(new data)
}
}
Я понимаю, что могу поместить весь свой существующий код в QThread
и заставить его посылать сигнал всякий раз, когда это делается для подключения к обновлению. Так будет проще. У кого-нибудь есть идеи, как решить эту проблему?
Решение
Если вы действительно не хотите исследовать многопоточное решение, что было бы лучше, вы можете использовать тайм-аут специального случая с 0. В основном, когда вы запускаете таймер с таймаутом 0, он запускает соответствующий код после обработки событий, которые в данный момент находятся в очереди событий. Итак, вы можете настроить что-то вроде этого:
class MyDialog : public QDialog
{
Q_OBJECT
public:
MyDialog()
{
m_step = 0;
QTimer::singleShot( 0, this, SLOT( Process() ) );
}
public slots:
void Process()
{
// do calculations
m_step++;
QTimer::singleShot( 0, this, SLOT( Redraw() ) );
if ( m_step != 1000 )
QTimer::singleShot( 0, this, SLOT( Process() ) );
}
void Redraw() { // do redrawing code here }
private:
int m_steps;
};
А затем скомбинируйте его с основным кодом Qt:
int main( int argc, char** argv )
{
QApplication app( argc, argv );
MyDialog dialog;
dialog.show();
return ( app.exec() );
}
Другие советы
Вы можете использовать QThread в своем приложении и выполнять вычисления в отдельном потоке. Вам нужно создать подкласс QThread и реализовать метод run ().
Вы можете создать класс калькулятора, добавить несколько сигналов в этот класс и подключить сигнал к слоту обновления вашего экранного виджета (в данном случае QGLWidget :: updateGL ()).
Вот грубый пример: (Все, что вам нужно, это создать поток и DisplayWidget в вашей функции main () и установить DisplayWidget потока.)
class Calculator: public QObject
{
Q_OBJECT
public:
Calculator();
void start();
signals:
void updateDisplayWidget(/* you can put the resulting data */);
};
class DisplayWidget(): public QGLWidget
{
Q_OBJECT
// override paint methods here
public slots:
void slotUpdateDisplayWidget(/* you can receive the resulting data*/);
};
class MyThread : public QThread
{
public:
void run();
void setDisplayWidget(DisplayWidget* displayWidget);
private:
Calculator mCalculator;
};
void MyThread::run()
{
mCalculator.start();
exec();
}
MyThread::setDisplayWidget(DisplayWidget* displayWidget)
{
displayWidget->moveToThread(this);
connect(&mCalculator, SIGNAL(updateDisplayWidget()), displayWidget, SLOT(slotUpdateDisplayWidget()));
}