Visualização científica com OpenGL e Qt
-
06-07-2019 - |
Pergunta
Eu estou tentando escrever um programa de visualização OpenGL para alguns dados científicos usando Qt. Eu gostaria de ser capaz de usar o meu programa existente inalterado e simplesmente ser capaz de chamar a glwidget e dizer-lhe para atualizar os dados no final de cada passo de tempo. No entanto, a fim de executar um programa Qt parece que você tem que usar QApplication
e depois qt.run()
que bloqueia a CPU.
Aqui está o código pseudo
main()
{
..set up stuff
myVisualizer = new myGLWidget();
for(int i=0;i<1000;i++)
{
..do calculations
myVisualizer.update(new data)
}
}
Eu percebo que eu poderia colocar todo o meu código existente em um QThread
e tê-lo enviar um sinal sempre que é feito para conectar-se a uma atualização. Seria apenas mais fácil dessa maneira. Alguém tem uma idéia de como resolver isso?
Solução
Se você realmente não quer para investigar a solução de rosca, o que seria mais agradável ao redor, você pode usar o tempo limite caso especial com 0. Basicamente, quando você executar um temporizador com um tempo limite de 0, corre o código adequado depois de processar os eventos que estão atualmente na fila de evento. Então, você poderia criar algo como isto:
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, em seguida, combiná-lo com o código principal Qt-adequada:
int main( int argc, char** argv )
{
QApplication app( argc, argv );
MyDialog dialog;
dialog.show();
return ( app.exec() );
}
Outras dicas
Você pode usar QThread em seu aplicativo e fazer os cálculos em um segmento separado. O que você tem a fazer é subclasse o QThread e implementar o método run ().
Você pode criar uma classe de calculadora e adicionar alguns sinais nessa classe e ligar o sinal para o slot atualização do seu widget de exibição (neste caso QGLWidget :: updateGL ()).
Aqui está um exemplo áspero: (. Tudo que você precisa é criar uma linha e DisplayWidget na sua função main () e definir DisplayWidget do segmento)
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()));
}