crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

11 страниц V   1 2 3 > »   
Ответить в данную темуНачать новую тему
> QPaintEvent, installEventFilter, QPainter, Overpainting
SABROG
  опции профиля:
сообщение 26.5.2009, 11:52
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Есть желание рисовать на дочерних окошках, причем хочется оставить их оригинальный render и рисовать поверх уже готовой картинки. Ввиду того, что дочерних элементов может быть сколько угодно, я не могу (а скорее не хочу) унаследоваться от каждого из них. Поэтому я использую installEventFilter.

Получился такой код:

bool MainWindow::eventFilter(QObject *o, QEvent *e)
{
    if (e->type() == QEvent::Paint && o->isWidgetType()) {
        QPaintEvent *pe = (QPaintEvent *)e;
        QWidget *w = (QWidget *)o;
        qDebug() << "painting:" << o;

        QObject::eventFilter(o, e); //пытаемся вызвать оригинальный обработчик, чтобы сам себя нарисовал
        QPainter p(w); // пытаемся нарисовать что-то поверх уже нарисованного
        p.setRenderHint(QPainter::Antialiasing,true);
        p.drawLine(QPointF(0,0),QPointF(20,90));
        return true; //говорим системе, что мы перехватили, чтобы не отправлял событие дальше, а следовательно и не перерисовывал
    } else {
        return QObject::eventFilter(o, e);
    }
}


Но не получается. Если убрать первый QObject::eventFilter(o, e);, то виджет рисуется поверх линии, т.е. она остается на заднем плане. Если оставить, то рисуется вообще только одна линия, оригинального изображения виджета нет. paintEvent вызвать напрямую не могу, т.к. он protected, render() и repaint() приводят к рекурсии, естественно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 26.5.2009, 12:01
Сообщение #2


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


Цитата(SABROG @ 26.5.2009, 12:52) *
оригинальный render

поясни пожалуйста что это такое?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 26.5.2009, 12:14
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


SABROG, первая мысля в слух: Стало быть фильтр вызывается до того, как событие будет доставленно адресату. Тогда надо помозговать исходя из этой ситуации

Несколько мимо темы, такой код:
Цитата(SABROG @ 26.5.2009, 15:52) *
QPaintEvent *pe = (QPaintEvent *)e;
QWidget *w = (QWidget *)o;
стиль приведения не С++ный, а Сишный, и уж точно не принятый в Qt (qobject_cast<>, надобы)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 26.5.2009, 12:15
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(kwisp @ 26.5.2009, 13:01) *
поясни пожалуйста что это такое?


Что-то типа QPixmap::grabWidget()
QPixmap pixmap(widget->size());
widget->render(&pixmap);

Оригинальный отрисовщик, который в paintEvent'e.

Цитата(Litkevich Yuriy @ 26.5.2009, 13:06) *
SABROG, первая мысля в слух: Стало быть фильтр вызывается до того, как событие будет доставленно адресату. Тогда надо помозговать исходя из этой ситуации


Давайте обмозгуем. Думаю postEvent тут тоже не поможет, т.к. опять будет рекурсия. Возможно флагами как-то, каждому объекту присвоить флаг (QMap)? Сначала вызвать оригинальный eventFilter, выставить flag в 1, потом как-то сгенерить опять событие, но при этом, чтобы старая картинка не затиралась.

Сообщение отредактировал SABROG - 26.5.2009, 12:17
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 26.5.2009, 12:19
Сообщение #5


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(SABROG @ 26.5.2009, 16:15) *
Думаю postEvent'ом тут тоже не обойтись, т.к. опять будет рекурсия.
дело даже не в рекурсии, обсуждалось недавно, что событие рисования посылать получается, да вот рисовальщик (QPainter) ругается.

Цитата(SABROG @ 26.5.2009, 16:15) *
потом попробовать отрисовать что-то поверх
а как попробовать рисовать мимо события рисования, на виджетах ведь можно рисовать только в их обработчике рисования.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 26.5.2009, 12:31
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Через флаг не получилось. Второй paintEvent затирает как-то все, что было до этого.

Цитата
а как попробовать рисовать мимо события рисования, на виджетах ведь можно рисовать только в их обработчике рисования.

В момент события QEvent::Paint из любого места, не обязательно внутри paintEvent метода.

Сообщение отредактировал SABROG - 26.5.2009, 12:36
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 26.5.2009, 12:39
Сообщение #7


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


Цитата(SABROG @ 26.5.2009, 13:31) *
Второй paintEvent затирает как-то все, что было до этого.

в доке написано что пред вызовом нового обработчика все стирается. чтоб этого избежать используют updete(QRect)

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

---------------
нет оказывается затруднительно рисовать на дочерних элементах даже если они на хозяине :(

Сообщение отредактировал kwisp - 26.5.2009, 12:46
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 26.5.2009, 12:51
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(kwisp @ 26.5.2009, 13:39) *
вообще как я понимаю. если дочерние элементы находятся на хозяине то рисовать на них нет труда в обраьботчике хозяина рисуй и всё.

А ты попробуй, ничего не получится. Как ни изгаляйся, а рисование на родителе всегда будет позади детей.

Цитата(kwisp @ 26.5.2009, 13:39) *
Может попробовать рисовать то что хочется на картинке а потом картинку лепить на дочернее окошко.

Если ты добавляешь детей в окно, то они отображаются. Если ты их скрываешь через setVisible(false)/hide(), то они естественно не будут вести себя как нормальные видимые дети, события обрабатываться не будут, анимация и обновление происходить не будут. Заставить их прорисоваться через QWidget::render можно, но вот как от них избавиться, чтобы реально их на экране не было - вопрос. На ум приходит что-то типа послать по далеким далеким координатам, за пределы виджета, но тут сразу возникает вопрос с корректировкой координат и событий клавиатуры и мыши. Опять же наверняка будут проблемы. Есть еще вариант с дополнительным виджетом-прослойкой. Эта тема как-раз создана для того, чтобы избежать такого решения, т.к. виджет-прослойка это не рисование, а по сути хак. Я вообще троллей не понимаю в связи с этим, вроде всё можно, вроде рисовать можно как хочешь, а вот поверх всего только в примере overpainting QGlWidget'a. Бред...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 26.5.2009, 12:53
Сообщение #9


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


Цитата(SABROG @ 26.5.2009, 13:31) *
В момент события QEvent::Paint из любого места, не обязательно внутри paintEvent метода.

гдеж еще если в eventFilter не получилось?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 26.5.2009, 12:56
Сообщение #10


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(kwisp @ 26.5.2009, 13:53) *
Цитата(SABROG @ 26.5.2009, 13:31) *
В момент события QEvent::Paint из любого места, не обязательно внутри paintEvent метода.

гдеж еще если в eventFilter не получилось?

В другом методе например, вызываемым внутри eventFilter'a.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

11 страниц V   1 2 3 > » 
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


16 чел. читают эту тему (гостей: 16, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 17.11.2024, 23:10