рисование на QWidget |
Здравствуйте, гость ( Вход | Регистрация )
рисование на QWidget |
voipp |
20.10.2009, 22:44
Сообщение
#1
|
Участник Группа: Участник Сообщений: 116 Регистрация: 20.10.2009 Из: Msk Пользователь №: 1166 Спасибо сказали: 0 раз(а) Репутация: 0 |
всем добрый вечер!
у меня такой вопрос, но сначала код
я прочитал что для рисования вызывается событие перерисовка(paintEvent).Вопрос 1 - в каком месте программы вызывается painEvent(я так понимаю что это либо в main.cpp либо в widget.h) и 2 - все нормально работает если перегрузить функцию paintEvent в конструкторе widget но как быть если я хочу paintEvent поместить не в этот конструктор а в другой класс? |
|
|
Litkevich Yuriy |
20.10.2009, 23:17
Сообщение
#2
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
Вопрос 1 - в каком месте программы вызывается painEvent(я так понимаю что это либо в main.cpp либо в widget.h) функция a.exec(); обрабатывает события которые пришли от ОСьки. Вызов paintEvent происходит в момент обработки событий, и это происходит регулярно, когда ось сообщает приложению, что его мордочка требует перерисовки.2 - все нормально работает если перегрузить функцию paintEvent в конструкторе widget в конструкторе ты ничего не перегружаешь! конструктор - функция, которая вызывается при создании объекта для установки начальных свойств (данных) если они необходимы.Перегрузка - это создание одноимённой функции к уже существующей, но с иными аргументами посмотри внимательно на функцию main: Первым придёт событие перерисовки, т.к. виджет верхнего уровня один, то только для него приложение вызовет Widget::paintEvent, затем управление вернётся в цикл обработки событий (внутри QApplication::exec), всякий раз когда, с окном что-то происходит, например, над ним двигается мышь, ОСька шлёт событие приложению. Т.к. все процессы в системе выполняются последовательно, то ОСь их просто записывает в очередь. А когда дело доходит до приложения оно из этой очереди извлекает события и вызывает соответствующие методы наследников класса QWidget. Всё это происходит (в рамках приложения) в нутри QApplication::execно как быть если я хочу paintEvent поместить не в этот конструктор а в другой класс? Я на 100% уверен, что реальная необходимость в этом нужна редко.В Qt используется компонентный подход к программированию. Компоненты между собой взаимодействуют посредством сигналов и слотов. Можно создать виджет со специфическими слотами, и сигналить ему, чтобы он что-то эдакое нарисовал на себе. |
|
|
voipp |
21.10.2009, 1:10
Сообщение
#3
|
Участник Группа: Участник Сообщений: 116 Регистрация: 20.10.2009 Из: Msk Пользователь №: 1166 Спасибо сказали: 0 раз(а) Репутация: 0 |
конструктор я имел ввиду класса PAINT а перегружал я paintEvent. Спасибо большое за дополнительные сведения по Qt !
|
|
|
voipp |
23.10.2009, 17:37
Сообщение
#4
|
Участник Группа: Участник Сообщений: 116 Регистрация: 20.10.2009 Из: Msk Пользователь №: 1166 Спасибо сказали: 0 раз(а) Репутация: 0 |
Я создал обычную функцию рисующую линию и в конструкторе класса mainwindow ее вызываю - но она ничего не рисует(вызов конструктора происходит до application.exec() )
|
|
|
BRE |
23.10.2009, 17:56
Сообщение
#5
|
Профессионал Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: 44 |
|
|
|
vanvo |
23.10.2009, 20:55
Сообщение
#6
|
Студент Группа: Участник Сообщений: 73 Регистрация: 18.8.2008 Пользователь №: 267 Спасибо сказали: 0 раз(а) Репутация: 0 |
Тоже недавно стал разбираться с 2D рисованием. Вопрос: как организовать отрисовку на widget'е, только после нажатия кнопки? И при каждом нажатии кнопки происходила перерисовка виджета.
Сообщение отредактировал vanvo - 23.10.2009, 20:57 |
|
|
Litkevich Yuriy |
23.10.2009, 21:14
Сообщение
#7
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
как организовать отрисовку на widget'е, только после нажатия кнопки? И при каждом нажатии кнопки происходила перерисовка виджета. Можно создать виджет со специфическими слотами, и сигналить ему, чтобы он что-то эдакое нарисовал на себе.
|
|
|
vanvo |
23.10.2009, 21:18
Сообщение
#8
|
Студент Группа: Участник Сообщений: 73 Регистрация: 18.8.2008 Пользователь №: 267 Спасибо сказали: 0 раз(а) Репутация: 0 |
Можно создать виджет со специфическими слотами, и сигналить ему, чтобы он что-то эдакое нарисовал на себе А можно поподробней? Ставит в тупик: Все рисование на виджет должно выполняться из paintEvent(). Т.е. в слоте нужно создавать событие? |
|
|
Litkevich Yuriy |
23.10.2009, 21:29
Сообщение
#9
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
Т.е. Идея:
Есть главный виджет (форма), на ней другие виджеты (контролы). Один из них называется Холст (Canvas). Из главного виджета рисуем на Холсте, т.е. весь код рисования сосредоточен в одной из функций главного виджета. Если со временем, нужно изменить программу мы переписываем этот самый код (т.е. главного виджета). Так было в Qt3, так есть у многих других библиотек. Идея Qt4: Нет Холста (такого класса), всякий виджет - холст. Создаём наследника QWidget - это будет замена Холста из первой идеи, весь код рисования помещаем в этот виджет (в отдельную функцию). Из PaintEvent вызываем эту функцию. Ну а функцию реализуем так как удобно. Далее можно пойти двумя дорогами: - 1 - Создать слот принимающий указатели на уже подготовленные массивы данных (X и Y) для рисования. Соответственно нужно завести в классе два локальных указателя, а в этом слоте лишь копировать аргументы слота в локальные переменные. В функции PaintEvent рисовать данные по получаемые по локальным указателям (если они не нулевые). - 2 - В Qt есть класс QImage (не виджет), на котором можно рисовать, где угодно и когда угодно. Хоть в другом потоке (виджеты не могут находится в других потоках, кроме основного). В классе нашего "холста" делаем слот принимающий ссылку на QImage, рисуем где хотим на QImage и передаём его через слот в наш "холст". Ну а в функции PaintEvent будем рисовать содержимое QImage. |
|
|
vanvo |
23.10.2009, 22:43
Сообщение
#10
|
Студент Группа: Участник Сообщений: 73 Регистрация: 18.8.2008 Пользователь №: 267 Спасибо сказали: 0 раз(а) Репутация: 0 |
Litkevich Yuriy, решил попробовать 1 дорогой. Для примера рисую эллипс, координаты которого передаю во внешнюю функцию класса.
Вот сам класс:
Вызываю updateHistogram из слота, обрабатывающего нажатие на кнопку в виде:
В этом случае нажатие на кнопку не приводит к изменению эллипса, но при изменении размера окна эллипс "перескакивает" на новые координаты. Пробовал создать искусственное событие ресайза в updateHistogram в виде:
Но это ничего не изменило. Прошу подсказать что исправить. Сообщение отредактировал vanvo - 23.10.2009, 22:47 |
|
|
Текстовая версия | Сейчас: 23.4.2024, 23:14 |