2015-04-30 8 views
0

У меня есть приложение, с помощью которого я могу нарисовать фрактал, используя QPainter. paintEvent функция заключается в следующем:Ошибка приложения Qt при вызове обновления несколько раз

void SimulationWindow::paintEvent(QPaintEvent*) 
{ 
    QPainter painter(this); 
    QPen my_pen; 
    initPainter(painter,my_pen); 
    initCoordsystem(painter); 
    if(m_mode == TRACE) 
    { 
     drawTrajectory(painter,my_pen); 
    } 
    else if(m_mode == FRACTAL) 
    { 
     drawFractal(painter, my_pen); 
    } 

    /*if(!m_isFinished) 
    { 
     update(); 
    }*/ 
} 

В этой версии, где последний if закомментирована, кажется, работает хорошо. Иначе он начнет рисовать фрактал непрерывно во время бега (до тех пор, пока не будет m_isFinished), но через секунду после запуска он сработает. Функция drawFractal выполняет только рисование фрактала на основе непрерывно вычисляемых результатов другой функцией, называемой computeFractal, которая работает в другом потоке. Логическая переменная m_isFinished устанавливается в начале этой функции как false, а в конце она установлена ​​в true.

Я действительно смущен этим, может ли кто-нибудь сказать мне, что может быть причиной аварии? Может быть, из-за computeFractal работает на другой поток? (QtConcurrent::run(this -> m_simulationwindow, &SimulationWindow::computeFractal);)

EDIT:

void SimulationWindow::drawFractal(QPainter &painter, QPen &my_pen) 
{ 
    for(int i = 0; i < m_colors.size(); ++i) 
    { 
     if(m_colors[i] == 0) 
     { 
      my_pen.setColor(Qt::red); 
      painter.setPen(my_pen); 
      painter.drawPoint(m_positions[i]); 
     } 

     else if(m_colors[i] == 1) 
     { 
      my_pen.setColor(Qt::green); 
      painter.setPen(my_pen); 
      painter.drawPoint(m_positions[i]); 
     } 

     else if(m_colors[i] == 2) 
     { 
      my_pen.setColor(Qt::blue); 
      painter.setPen(my_pen); 
      painter.drawPoint(m_positions[i]); 
     } 
    } 
} 

drawTrajectory не вызывается вовсе не в этом случае.

+0

Где он точно падает? Вы пытались запустить программу в отладчике? Также вы можете отправить код двух функций drawTrajectory и drawFractal? –

+0

@ this.lau_: Я добавил, что вы просили. На данный момент я не знаю, где он падает. – zerge

+0

Вы уверены, что m_positions точно такого же размера, как m_colors? Возможно, добавьте некоторую проверку работоспособности в верхней части функции drawFractal во время отладки. –

ответ

2

EDIT: update() Фактически график a paintEvent(), что означает, что он не вызывает бесконечную рекурсию. Это может привести только к repaint().

Предложение:

Вы могли настроить QTimer, что каждый бит второго обновления вызовов, а затем контролировать ваше выполнение рендеринга/фреймрейт таким образом.

QTimer *timer = new QTimer(this); 

connect(timer, SIGNAL(timeout(), this, SLOT(myUpdate())); 
timer->start(1000f/60f); //every 1/60 of a second it times out 

void MyWindow::myUpdate() 
{ 
    //do your logic here 
    update(); 
} 

А потом на paintEvent() вы должны оставить только фактическую визуализацию.

EDIT: Qt имеет другие решения для управления временем, и это может помочь вам визуализировать, например. QElapsedTimer

+0

Я пробовал ваш метод, к сожалению, он не работал. Я начал таймер с начала (1000.0f), поэтому обновление вызывалось каждую секунду, но update() вызывался только 3 раза, и он разбился. Возможно, что-то другое вызывает проблемы. – zerge

+0

Вы пробовали работать в режиме отладки, показывает ли он, где он падает? – KuramaYoko

+0

Каждый раз, когда вызывается update(), также вызывается paintEvent().** WRONG ** Из документов Qt: ** Предупреждение: ** Если вы вызываете функцию repaint() в функции, которая сама может быть вызвана из paintEvent(), вы можете получить бесконечную рекурсию. Функция update() никогда не вызывает рекурсии. – Greenflow