Отстающие приложение QWidget's paintEvent () - PullRequest
1 голос
/ 25 февраля 2010

Я изучаю и модифицирую пример магниты на холодильник , и последнее, что я попытался сделать, это нарисовать несколько меток и линий, которые должны быть на заднем плане.

Посмотрев вокруг, пытаясь понять, как рисовать метки и линии, я понял, что могу переопределить QWidget paintEvent (), чтобы сделать это. Однако после того, как я это сделал, приложение стало тормозить, и я обнаружил, что это вызвано тем, что paintEvent () вызывается в, казалось бы, бесконечном цикле.

Пытаясь выяснить, как это исправить, я переместил код, который рисовал метки и линии, в конструктор класса. Только ярлыки были нарисованы на приложении, хотя. После этого я оставил метки в конструкторе, но переместил код, который рисует линии, обратно в paintEvent (). Это сработало, линии были нарисованы, как и ожидалось, и paintEvent () вызывался только при перетаскивании объектов вокруг.

Почему линии не были нарисованы на конструкторе, и почему paintEvent () попал в бесконечный цикл?

Вот фрагмент кода, который должен рисовать метки и линии:

QPen pen(Qt::lightGray, 0, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin);
QPainter paint(this);
paint.setPen(pen);
int scale = 20;
for(int x=0; x<25; x++){
    QString timetext= "0"+QString::number(x)+":00";
    QLabel *time= new QLabel(timetext,this);
    time->move(x*scale,2);
    time->show();
    paint.drawLine(x*scale,12,x*scale,400);
}

Ответы [ 2 ]

9 голосов
/ 25 февраля 2010

Вы добавляете объекты в дерево виджетов во время paintEvent(). Это считается неудачей. Планировщик Qt для повреждения и рисования увидит, что нужно нарисовать нового потомка, и попытается управлять этим, и, скорее всего, результатом будет цикл. Если вы переопределите paintEvent (), сделайте все рисование одним и тем же объектом! Золотое правило: paintEvent() только для рисования! Не для создания объектов или чего-либо еще.

Сделай так:

QFont font(painter.font());
font.setBold(true);
painter.setFont(font);
painter.fillRect(rect(), Qt::black);
painter.setPen(Qt::white);
painter.drawText(rect(), Qt::AlignCenter, tr("White text on dark background. Awesome."));
2 голосов
/ 25 февраля 2010

Почему линии не были нарисованы на конструкторе?

Я думаю, что они были, но они были "стерты" следующим вызовом paintEvent (), в котором вы больше не рисовали линии ...

Почему paintEvent () попал в бесконечный цикл?

Я думаю, это может быть связано с вашим временем-> show (); который вызывается 25 раз каждый раз, когда вызывается paintEvent ... Я не уверен в этом, но, поскольку в качестве виджета в качестве родителя, когда вы вызываете "show", возможно, он вызывает "show" для своего родителя, поэтому вызывает paintEvent. ... Вы знаете, что я имею в виду ...

Поскольку Ипнос дал вам решение, я обращаюсь к нему:)

...