У меня есть приложение, с помощью которого я могу нарисовать фрактал, используя QPainter
,
paintEvent
Функция заключается в следующем:
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
логическая переменная устанавливается в ложь в начале этой функции, а в конце она устанавливается в истину.
Я действительно запутался с этим, может кто-нибудь сказать мне, пожалуйста, что может быть причиной аварии? Может быть, из-за computeFractal работает в другом потоке?
(QtConcurrent::run(this -> m_simulationwindow, &SimulationWindow::computeFractal);
)
РЕДАКТИРОВАТЬ:
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
не вызывается вообще в этом случае.
РЕДАКТИРОВАТЬ: update()
на самом деле график это 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()
Вы должны оставить только фактический рендеринг.
РЕДАКТИРОВАТЬ: Qt имеет другие решения для контроля времени, которые могут помочь вам визуализировать, например, QElapsedTimer