Russian Qt Forum
Сентябрь 30, 2024, 18:35 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 ... 5   Вниз
  Печать  
Автор Тема: Портирование рисования  (Прочитано 26054 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Декабрь 22, 2013, 12:31 »

Добрый день

Есть старый класс рисования, конструктор
Код
C++ (Qt)
OldPainter::OldPainter( Window * win )
{
GrafPtr port = win->GetPort();
::SetGWorld(port, ::GetMainDevice());   // порт (окно), экран
//...
}
После этого идет рисование нативными ф-циями, напр PaintRect() и все такое. Поскольку вывод double-buffered, никаких изменений на экране еще не происходит. Потом делается такой финт ушами
Код
C++ (Qt)
OldPainter::~OldPainter( void )
{
//..
::QDFlashPortBuffer(..);
//..
}
И окно прекрасно обновляется, причем немедленно.

Как же мне это перевести на Qt  Непонимающий

Спасибо
Записан
Bepec
Гость
« Ответ #1 : Декабрь 22, 2013, 12:37 »

Вариант "сохранить логику и переписать на QPainter" не предлагать?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Декабрь 22, 2013, 12:47 »

Вариант "сохранить логику и переписать на QPainter" не предлагать?
Так а каким образом ее хранить? Покажите на примере (в псевдокоде конечно)
Записан
Bepec
Гость
« Ответ #3 : Декабрь 22, 2013, 13:25 »

Эм... Без приведённого кода никак, но псевдокод.

Было
Код:
PaintRect(бла бла прямоугольник 40 на 40);
SetPixel(бла бла в центре красная точка);
if (какие то данные)
    LineTo(бла бла соединяем все углы с центром);

Станет
Код:
QPainter painter(this);
painter.drawRect(0,0,40,40);
painter.drawPoint(20,20); // + color red
if (какие то данные)
    painter.lineTo(и ещё 3 раза, соединяем все углы с центром);

PS если вы умолчали о каких то подводных камнях старого класса или условностей - не обессудьте, сами виноваты Веселый
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Декабрь 22, 2013, 13:36 »

Все рисуем в backbuffer, по завершении говорим окну update и в его paintEvent рисуем backbuffer.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Декабрь 22, 2013, 13:48 »

Код:
QPainter painter(this);
painter.drawRect(0,0,40,40);
painter.drawPoint(20,20); // + color red
if (какие то данные)
    painter.lineTo(и ещё 3 раза, соединяем все углы с центром);
Это было бы просто замечательно, перевести код на QPainter не проблема. Но ведь я получу по дюнделю создав QPainter(QWidget *) вне paintEvent? Или есть ходы?

Все рисуем в backbuffer, по завершении говорим окну update и в его paintEvent рисуем backbuffer.
update не вызывает немедленной перерисовки - нужно получить событие. Да, есть repaint, но на OSX он == update
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #6 : Декабрь 22, 2013, 13:53 »

update не вызывает немедленной перерисовки - нужно получить событие. Да, есть repaint, но на OSX он == update
Конечно не вызывает, рисовать на виджет можно только в определенный момент - событие paintEvent. Вы можете только попросить сгенерировать такое событие.
Записан
Bepec
Гость
« Ответ #7 : Декабрь 22, 2013, 13:55 »

Эмм.. у вас же обычное рисование.

Просто рисуете всё на буфере - картинке и по мере необходимости update с перерисовкой картинки. Есть проблема? Нет проблемы.

Есть ещё способ с installEventFilter - перехватывать paintEvent, но там со сложными виджетами засада, типа view и прочего.

PS опять не вижу проблемы ^.^ Надо очки поменять что ли...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Декабрь 22, 2013, 14:21 »

PS опять не вижу проблемы ^.^ Надо очки поменять что ли...
Псевдокод
Код
C++ (Qt)
if (1) {
OldPainter op(win);
op.PaintRect(&R);
}   // здесь деструктор вытолкнет нарисованный Rect на экран
while (true) {
// здесь что-то делаем достаточно долго, напр неск секунд
}
Старый код рассчитывает что экран уже обновлен. Чтобы добиться того же с Qt нужно что-то делать, но что? Вызов processEvents может оказаться совсем не безобиден

Конечно не вызывает, рисовать на виджет можно только в определенный момент - событие paintEvent. Вы можете только попросить сгенерировать такое событие.
Хммм....  ну а так ли уж это бесспорно? Да и рисование в pixMap здесь хорошего впечатления не производит
« Последнее редактирование: Декабрь 22, 2013, 15:27 от Igors » Записан
Bepec
Гость
« Ответ #9 : Декабрь 22, 2013, 14:33 »

Приводите пример рисования, мы его разберём. Как я и написал с самого начала - есть ограничения, которые вы не привели.

По простому - разбить на итерации. Нужен квадрат - рисуем квадрат.

Было
Код:
OldPainter op(win);
op.PaintRect(&R);
while (true) {
// здесь что-то делаем достаточно долго, напр неск секунд
}

Стало
Код:
QPainter painter();
painter.begin(&fon); // рисуем на пиксмапе в любое время, когда надо обновляем.
painter.drawRect(bla bla розового цвета);
painter.end();
update();
while (true) {
// здесь что-то делаем достаточно долго, напр неск секунд
}

По-моему вполне нормально переносится. Месяца три назад помогал одному человеку похожее сделать.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Декабрь 22, 2013, 14:36 »

По-моему вполне нормально переносится.
Ничего не произойдет от такого update.
События никто не обрабатывает.
Записан
Bepec
Гость
« Ответ #11 : Декабрь 22, 2013, 14:41 »

Во 1 это псевдокод.
Во 2 нужна вся картина и тогда уже будем приводит реально работающий код ^.^ Думаю для всех участвующих в обсуждении цикл событий Qt знаком. Как и методы работы с ним.

Добавим processEvent's, или же  ресурсоёмкие действия вынесем в другую функцию, а можно вообще в отдельный поток. Всё что угодно Подмигивающий
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #12 : Декабрь 22, 2013, 15:22 »

Старый код рассчитывает что экран уже обновлен.
Когда? Объект op не разрушался.

Хммм....  ну а так ли уж это бесспорно?
Для основных платформ (win / X) так.
Внутри вашего top-window вы можете делать что хотите (рисовать на виджеты или QImage или куда хотите), но пользователь это увидит только когда графическая подсистема ОС попросит программу отрисовать его top-window послав ему сообщение.

Да и рисование в pixMap здесь хорошего впечатления не производит
Ну Qt всегда рисует в QImage - она буфферизирует отрисовку.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Декабрь 22, 2013, 15:34 »

Когда? Объект op не разрушался.
Точно, подправил

Ну Qt всегда рисует в QImage - она буфферизирует отрисовку.
Даже там где ОС обеспечивает double-buffer? Не уверен. Кстати нативные ф-ции для немедленного обновления есть, причем не одна. Ладно, не суть.

Во 1 это псевдокод.
Во 2 нужна вся картина и тогда уже будем ..
Пожалуйста, "тарахтелку" не включайте  Улыбающийся

Хорошо, зайдем с др стороны: а как мне добиться получения paintEvent не трогая при этом др события ? 
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #14 : Декабрь 22, 2013, 15:39 »

Кстати нативные ф-ции для немедленного обновления есть, причем не одна.
Это какие?
Записан
Страниц: [1] 2 3 ... 5   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.347 секунд. Запросов: 23.