Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Гурман от Январь 17, 2017, 14:38



Название: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Гурман от Январь 17, 2017, 14:38
В который раз столкнулся - класс наследует QWidget, в нём переопределён paintEvent(), и при вызове update() или repaint() он не вызывается. Всякий раз находил обходные пути - сейчас вместо QWidget унаследовал QLabel, у него при update вызывается paintEvent(). То есть, буквально поменял родительский класс - и заработало как надо. У QLabel есть лишний для меня функционал, да и чёрт с ним.

Но хотя бы для спортивного интереса любопытно - почему так? Ковырять для этого исходники некогда - может уже кто-то ковырял?


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: lit-uriy от Январь 17, 2017, 14:40
QWidget в отличие от QFrame (->Qlabel) не определяет некоторые базовые методы связанные с размерами виджета

Полезный раздел в документации Пользовательские виджеты в компоновщиках (http://www.doc.crossplatform.ru/qt/4.5.0/layout.html#custom-widgets-in-layouts), особенно место "Вызывайте QWidget::updateGeometry() всякий раз, когда ..."


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Гурман от Январь 17, 2017, 14:46
QWidget в отличие от QFrame (->Qlabel) не определяет некоторые базовые методы связанные с размерами виджета

Странно... у виджета же есть geometry(), размеры заданы в дизайнере.

То есть, достаточно QFrame наследовать? Попробую... - да, действительно. При наследовании QFrame работает нормально.


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: lit-uriy от Январь 17, 2017, 14:47
Обновил свой пост, прочитай пожалуйста


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Гурман от Январь 17, 2017, 14:59
Ну это там всё относится к компоновке, а не к рисованию - в моём случае пока не важно, автоматический компоновщик пока что не используется. Но всё равно может пригодиться, спс.


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Old от Январь 17, 2017, 15:42
Ну это там всё относится к компоновке, а не к рисованию - в моём случае пока не важно, автоматический компоновщик пока что не используется. Но всё равно может пригодиться, спс.
А вы можете компилируемый пример показать, где не вызывается paintEvent?
Никогда с таким не сталкивался, куча виджетов наследуется от QWidget и все нормально.


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Гурман от Январь 17, 2017, 16:08
А вы можете компилируемый пример показать, где не вызывается paintEvent?
Никогда с таким не сталкивался, куча виджетов наследуется от QWidget и все нормально.

Да не, для этого его создавать отдельно надо. На пальцах всё просто было:

Код:
class TLwidget : public QWidget
{
...
    void timeout();
...
protected:
    void paintEvent(QPaintEvent*);
...
};

void TLwidget::timeout()
{
...
    update();
    qDebug()<<"drawn";
}

void TLwidget::paintEvent(QPaintEvent*)
{
    QPainter p(this);
    p.fillRect( geometry(), QBrush(backcolor) );
    p.setPen( QPen(forecolor) );
    p.setFont(font);
    p.drawText( xpos, ypos, text );
}

Ну единственное, что это ещё и плагин дизайнера, с пропертями и всякой такой всячиной. Но это всё не существенно - при наследовании от QWidget текста и фона на виджете нет (в отладку печатает drawn), при наследовании от QFrame всё есть.


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Old от Январь 17, 2017, 16:33
А почему вы здесь используете geometry?
Код
C++ (Qt)
   p.fillRect( geometry(), QBrush(backcolor) );
 

Здесь должен быть rect(). Посмотрите что возвращает geometry().


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Old от Январь 17, 2017, 16:34
А вот тестовый пример, где все работает:
Код
C++ (Qt)
#include "widget.h"
#include <QPainter>
#include <QTimer>
 
Widget::Widget( QWidget *parent ) :
QWidget( parent ),
tick( true ),
timer( new QTimer( this ) )
{
connect( timer, SIGNAL(timeout()), SLOT(timeout()) );
timer->setInterval( 1000 );
timer->setSingleShot( false );
timer->start();
}
 
void Widget::timeout()
{
tick = !tick;
update();
}
 
void Widget::paintEvent( QPaintEvent * )
{
QPainter p( this );
p.fillRect( rect(), QBrush( tick? Qt::blue : Qt::darkBlue ) );
p.setPen( QPen( Qt::yellow ) );
p.drawText( 20, 20, "Test string" );
}
 

Архив нужно приложить?


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Гурман от Январь 17, 2017, 16:52
А почему вы здесь используете geometry?
Код
C++ (Qt)
   p.fillRect( geometry(), QBrush(backcolor) );
 

Здесь должен быть rect(). Посмотрите что возвращает geometry().


Да не важно - paintEvent() вообще не вызывался. Там как раз был отладочный qDebug()<<geometry(); в начале, он не выводил ничего. То есть совсем ничего. Для QFrame там frameRect() сейчас.


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Гурман от Январь 17, 2017, 16:53
Архив нужно приложить?

Нет, не нужно. Я же говорю - поменял QWidget на QFrame и использовал frameRect() - всё заработало.

Мало ли... во-первых, это у меня кастомный плагин, во-вторых, этот виджет привязан к QWidgetItem, лежащему на графической сцене.




Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Old от Январь 17, 2017, 16:55
Я же говорю - поменял QWidget на QFrame и использовал frameRect() - всё заработало.
А если сейчас обратно поменять на QWidget? Если не заработает, выкладывайте исходник этого виджета. :)


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Гурман от Январь 17, 2017, 16:56
Я же говорю - поменял QWidget на QFrame и использовал frameRect() - всё заработало.
А если сейчас обратно поменять на QWidget? Если не заработает, выкладывайте исходник этого виджета. :)

Не заработает. Ничего менять не буду - уже другим занят. Не пришлю. Proprietary.  :)


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Гурман от Январь 17, 2017, 17:22
Да, ещё, кстати забыл упомянуть - это всё происходит в Android. В дизайнере на десктопе под Linux этот виджет рисует только фон, текст почему-то вообще не появляется (некогда сейчас разбираться). Но с QWidget и в дизайнере даже фона не было.


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: panAlexey от Январь 17, 2017, 17:40
Но хотя бы для спортивного интереса любопытно - почему так? Ковырять для этого исходники некогда - может уже кто-то ковырял?
А версия Qt какая?
На 473 и 421 не встречался с такими фокусами.
ПС. Обожаю виджеты самописки - много геморроя убирают...


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: Гурман от Январь 17, 2017, 17:54
5.6.1

4-й Qt в Android не работает.

ПС. Обожаю виджеты самописки - много геморроя убирают...

Это сарказм такой?... Геморроя ещё больше - совершенно не прозрачно когда вызываются методы для пропертей, когда что надо пересчитывать заново и т.д. Впрочем это уже к вопросу темы не имеет отношения - просьба не развивать.


Название: Re: Что всё-таки не так с paintEvent() после QWidget::update()?
Отправлено: panAlexey от Январь 19, 2017, 00:12
5.6.1

4-й Qt в Android не работает.

ПС. Обожаю виджеты самописки - много геморроя убирают...

Это сарказм такой?... Геморроя ещё больше - совершенно не прозрачно когда вызываются методы для пропертей, когда что надо пересчитывать заново и т.д. Впрочем это уже к вопросу темы не имеет отношения - просьба не развивать.


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