OpenGL 및 Qt를 사용한 과학적 시각화
-
06-07-2019 - |
문제
Qt를 사용하여 일부 과학 데이터에 대한 OpenGL 시각화 프로그램을 작성하려고 합니다.나는 기존 프로그램을 변경하지 않고 사용할 수 있고 glwidget을 호출하여 각 시간 단계가 끝날 때 데이터를 업데이트하도록 지시할 수 있기를 원합니다.그러나 Qt 프로그램을 실행하려면 다음을 사용해야 하는 것 같습니다. QApplication
그런 다음 qt.run()
CPU를 차단하는 것입니다.
다음은 의사 코드입니다.
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-Proper 메인 코드와 결합하십시오.
int main( int argc, char** argv )
{
QApplication app( argc, argv );
MyDialog dialog;
dialog.show();
return ( app.exec() );
}
다른 팁
애플리케이션에서 QThread를 사용하고 별도의 스레드에서 계산을 수행할 수 있습니다.당신이 해야 할 일은 QThread를 서브클래싱하고 run() 메소드를 구현하는 것입니다.
계산기 클래스를 생성하고 해당 클래스에 일부 신호를 추가한 다음 해당 신호를 디스플레이 위젯의 업데이트 슬롯(이 경우 QGLWidget::updateGL())에 연결할 수 있습니다.
대략적인 예는 다음과 같습니다.(main() 함수에서 스레드와 DisplayWidget을 생성하고 스레드의 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()));
}