Visualizzazione scientifica con OpenGL e Qt
-
06-07-2019 - |
Domanda
Sto cercando di scrivere un programma di visualizzazione OpenGL per alcuni dati scientifici usando Qt. Vorrei essere in grado di utilizzare il mio programma esistente invariato e semplicemente essere in grado di chiamare il glwidget e dirgli di aggiornare i dati alla fine di ogni passaggio temporale. Tuttavia, per eseguire un programma Qt sembra che devi usare QApplication
e poi qt.run ()
che blocca la CPU.
Ecco lo pseudo codice
main()
{
..set up stuff
myVisualizer = new myGLWidget();
for(int i=0;i<1000;i++)
{
..do calculations
myVisualizer.update(new data)
}
}
Mi rendo conto che potrei mettere tutto il mio codice esistente in un QThread
e farlo inviare un segnale ogni volta che viene fatto per connettersi a un aggiornamento. In questo modo sarebbe più semplice. Qualcuno ha idea di come risolverlo?
Soluzione
Se davvero non vuoi investigare la soluzione threaded, che sarebbe più bella in giro, puoi usare il timeout del caso speciale con 0. Fondamentalmente, quando esegui un timer con un timeout di 0, esegue codice appropriato dopo l'elaborazione degli eventi che si trovano attualmente nella coda degli eventi. Quindi, potresti impostare qualcosa del genere:
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;
};
E poi combinalo con il codice principale appropriato di Qt:
int main( int argc, char** argv )
{
QApplication app( argc, argv );
MyDialog dialog;
dialog.show();
return ( app.exec() );
}
Altri suggerimenti
Puoi usare QThread nella tua applicazione ed eseguire i calcoli in un thread separato. Quello che devi fare è sottoclassare QThread e implementare il metodo run ().
Puoi creare una classe calcolatrice e aggiungere alcuni segnali in quella classe e connetterlo allo slot di aggiornamento del tuo widget di visualizzazione (in questo caso QGLWidget :: updateGL ()).
Ecco un esempio approssimativo: (Tutto quello che devi fare è creare un thread e DisplayWidget nella tua funzione main () e impostare DisplayWidget del thread.)
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()));
}