Visualisation scientifique avec OpenGL et Qt
-
06-07-2019 - |
Question
J'essaie d'écrire un programme de visualisation OpenGL pour certaines données scientifiques en utilisant Qt. J'aimerais pouvoir utiliser mon programme existant sans le modifier et pouvoir simplement appeler le glwidget et lui dire de mettre à jour les données à la fin de chaque pas de temps. Cependant, pour exécuter un programme Qt, vous devez utiliser QApplication
, puis qt.run ()
, qui bloque le cpu.
Voici le pseudo code
main()
{
..set up stuff
myVisualizer = new myGLWidget();
for(int i=0;i<1000;i++)
{
..do calculations
myVisualizer.update(new data)
}
}
Je réalise que je pourrais mettre tout mon code existant dans un QThread
et le laisser envoyer un signal chaque fois que cela est fait pour se connecter à une mise à jour. Ce serait juste plus facile de cette façon. Quelqu'un a-t-il une idée de la façon de résoudre ce problème?
La solution
Si vous ne voulez vraiment pas explorer la solution threadée, ce qui serait mieux, vous pouvez utiliser le délai d'expiration des cas spéciaux avec 0. En gros, lorsque vous exécutez une minuterie avec un délai d'expiration de 0, le programme code approprié après le traitement des événements qui se trouvent actuellement dans la file d'attente d'événements. Donc, vous pouvez configurer quelque chose comme ceci:
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;
};
Et combinez-le ensuite avec le code principal Qt-proper:
int main( int argc, char** argv )
{
QApplication app( argc, argv );
MyDialog dialog;
dialog.show();
return ( app.exec() );
}
Autres conseils
Vous pouvez utiliser QThread dans votre application et effectuer les calculs dans un thread séparé. Ce que vous devez faire est de sous-classer QThread et d’implémenter la méthode run ().
Vous pouvez créer une classe de calculatrice et y ajouter des signaux, puis connecter le signal à l'emplacement de mise à jour du widget d'affichage (dans ce cas, QGLWidget :: updateGL ()).
Voici un exemple approximatif: (Tout ce que vous avez à faire est de créer un fil et DisplayWidget dans votre fonction main () et de définir le DisplayWidget du fil.)
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()));
}