Научная визуализация с OpenGL и Qt - PullRequest
2 голосов
/ 18 июня 2009

Я пытаюсь написать программу визуализации OpenGL для некоторых научных данных, используя Qt. Я хотел бы иметь возможность использовать мою существующую программу без изменений и просто вызывать glwidget и сообщать ему об обновлении данных в конце каждого временного шага. Однако, чтобы запустить программу Qt, вам нужно использовать QApplication, а затем qt.run(), который блокирует процессор.

Вот псевдокод

main()

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

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

Я понимаю, что могу поместить весь свой существующий код в QThread и заставить его отправлять сигнал всякий раз, когда это делается для подключения к обновлению. Так будет проще. У кого-нибудь есть идеи, как это решить?

Ответы [ 2 ]

2 голосов
/ 18 июня 2009

Если вы действительно не хотите исследовать многопоточное решение, что было бы лучше, вы можете использовать тайм-аут специального случая с 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:

int main( int argc, char** argv )
{
    QApplication app( argc, argv );
    MyDialog dialog;
    dialog.show();
    return ( app.exec() );
}
0 голосов
/ 18 июня 2009

Вы можете использовать QThread в своем приложении и выполнять вычисления в отдельном потоке. Что вам нужно сделать, так это создать подкласс QThread и реализовать метод run ().

Вы можете создать класс калькулятора, добавить несколько сигналов в этот класс и подключить сигнал к слоту обновления вашего экранного виджета (в данном случае QGLWidget :: updateGL ()).

Вот грубый пример: (Все, что вам нужно, это создать поток и DisplayWidget в вашей функции main () и установить 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()));
}
...