2009-06-18 5 views
2

Ich versuche, ein OpenGL-Visualisierungsprogramm für einige wissenschaftliche Daten mit Qt zu schreiben. Ich möchte in der Lage sein, mein bestehendes Programm unverändert zu verwenden und einfach das glwidget aufrufen zu können und ihm zu sagen, dass es die Daten am Ende jedes Zeitschritts aktualisieren soll. Um jedoch ein Qt-Programm auszuführen, müssen Sie QApplication und dann qt.run() verwenden, was die CPU blockiert. HierWissenschaftliche Visualisierung mit OpenGL und Qt

ist der Pseudocode

main() 

{ 
    ..set up stuff 
    myVisualizer = new myGLWidget(); 

    for(int i=0;i<1000;i++) 
    { 
     ..do calculations 
     myVisualizer.update(new data) 
    } 
} 

Ich weiß, dass ich alle meine vorhandenen Code in eine QThread setzen könnte und haben sie ein Signal senden, wenn es fertig ist, um ein Update zu verbinden. Es wäre einfach einfacher so. Hat jemand eine Idee, wie man das löst?

Antwort

2

Wenn Sie wirklich nicht wollen Untersuchen Sie die Thread-Lösung, die rundum schöner wäre. Sie können das Sonderfall-Timeout mit 0 verwenden. Wenn Sie einen Timer mit einem Timeout von 0 ausführen, wird nach der Verarbeitung der Ereignisse, die derzeit auf dem Server ausgeführt werden, der entsprechende Code ausgeführt Ereigniswarteschlange So können Sie so etwas wie dies ein:

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; 
}; 

Und dann verbinden sich mit dem Qt-korrekten Hauptcode:

int main(int argc, char** argv) 
{ 
    QApplication app(argc, argv); 
    MyDialog dialog; 
    dialog.show(); 
    return (app.exec()); 
} 
+0

Upvoted diese Antwort als einen Timer verwenden ist die Art, wie ich es tun würde. Kein Bedarf für einen separaten Thread. Allerdings sehe ich nicht die Notwendigkeit der Single-Shot-Timer auf den Redraw-Slot und auch, warum das Widget eine Unterklasse von QDialog und nicht QGLWidget ist. – Troubadour

0

Sie können QThread in Ihrer Anwendung verwenden und die Berechnungen in einem separaten Thread durchführen. Was Sie tun müssen, ist die Unterklasse der QThread und implementieren Sie die run() -Methode.

Sie können eine Rechnerklasse erstellen und einige Signale in dieser Klasse hinzufügen und das Signal an den Aktualisierungssteckplatz Ihres Anzeige-Widgets anschließen (in diesem Fall QGLWidget :: updateGL()).

ist hier ein grobes Beispiel: (. Alles, was Sie haben, ist ein Gewinde und DisplayWidget in Ihrer Funktion main() zu erstellen und der Threads DisplayWidget eingestellt)

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())); 
} 
+0

wäre nicht der Schlitz in DisplayWidget im Kontext des QThread laufen? –

+0

nein, Qt Main Event Loop behandelt die Threads und alles wird gut funktionieren. – alisami