Russian Qt Forum
Июля 07, 2025, 09:46 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

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

Сообщений: 11445


Просмотр профиля
« : Января 10, 2014, 11:53 »

Добрый день

Хотелось бы иметь возможность рисовать "поверх" всех виджетов, типа как делает drag'n drop, Пример:

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

В нативняке техника рисования на слое известна уже более 10 лет. А как это сделать средствами Qt?

Спасибо
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #1 : Января 10, 2014, 12:19 »

QRubberBand ?
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Января 10, 2014, 12:31 »

QRubberBand ?
Да, в этом направлении, но QRubberBand  hard-coded, больше чем он дает по дефаулту не получить.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Января 10, 2014, 12:33 »

Хотелось бы иметь возможность рисовать "поверх" всех виджетов, типа как делает drag'n drop
drag'n drop рисует в с воём собственном окне)

Можно на главном окне создать виджет  и на нём рисовать.
Можно вообще поместить отдельное прозрачное окно поверх нарисованного и уже на нём рисовать.
Записан

Qt 5.11/4.8.7 (X11/Win)
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #4 : Января 10, 2014, 12:45 »

Можно на главном окне создать виджет  и на нём рисовать.
Можно вообще поместить отдельное прозрачное окно поверх нарисованного и уже на нём рисовать.

+1
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Января 10, 2014, 13:51 »

drag'n drop рисует в с воём собственном окне)
На OSX дело сводится к вызову системного DnD. Есть QDesktopWidget - он имеет именно тот нативный тип окна что предназначен для этих целей. Но как мне прорваться к рисованию на нем?

Можно на главном окне создать виджет  и на нём рисовать.
Можно вообще поместить отдельное прозрачное окно поверх нарисованного и уже на нём рисовать.
Так новое окно становится в фокус и бросает тень. С виджетом буду пробовать
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #6 : Января 10, 2014, 14:55 »

Есть QDesktopWidget - он имеет именно тот нативный тип окна что предназначен для этих целей. Но как мне прорваться к рисованию на нем?
Средствами Qt навряд-ли получится рисовать на root-овом окне.

Цитировать
Так новое окно становится в фокус и бросает тень. С виджетом буду пробовать
А что, разве на OSX нельзя иметь окно без декораций и теней?
Записан

Qt 5.11/4.8.7 (X11/Win)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Января 11, 2014, 12:04 »

C QDesktop.. видимо глухо - ничего не дают.  Вставить в окно прозрачный виджет и на нем рисовать - работает, но при попытке перерисовать этот виджет вызывается paint всего окна, причем дважды (почему - хз). Поэтому сосредоточился на варианте "прозрачное окно поверх". Смену фокуса убрал с помощью WA_ShowWithoutActivation. Тень убрал вызовом нативной ф-ции, ну ничего, боковым зрением видел в Qt5.x это уже есть, потом вычищу нативняк. Таким образом я могу рисовать "поверх" и при этом никаких paint для нижнего окна не вызывается, и никаких изменений в коде нижнего не требуется - хорошо.

Но при этом я не учел маленькой вещи - надо рисовать XOR'ом, а он работает "в пределах верхнего окна" т.е. никак не учитывает нижнее. Можно конечно сначала скопировать нижнее в верхнее - но это совсем коряво Плачущий  Как это порешать?

Спасибо
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #8 : Января 11, 2014, 14:40 »

Можно конечно сначала скопировать нижнее в верхнее - но это совсем коряво Плачущий  Как это порешать?
Дык, разве есть варианты?
Если Qt<5, то можно легко через QWidget::windowSurface() через приватный инклюдник добраться до double-buffer основного окна.
Записан

Qt 5.11/4.8.7 (X11/Win)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Января 11, 2014, 18:37 »

Дык, разве есть варианты?
Если Qt<5, то можно легко через QWidget::windowSurface() через приватный инклюдник добраться до double-buffer основного окна.
Можно и просто через QPixmap::grabWindow (работает и для окон с OpenGL). Ну а дальше-то что? Напр нужно провести хоr-линию, не буду же я выцарапывать и инвертировать по пикселю  Плачущий  Остается скопировать все содержимое в верхнее, ну как бы покрыть окно его же копией и там уже xor-ить. Но тогда придется следить за изменением нижнего - не кайф
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #10 : Января 11, 2014, 23:58 »

Напр нужно провести хоr-линию, не буду же я выцарапывать и инвертировать по пикселю  Плачущий

и все же... QRubberBand? Улыбающийся
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #11 : Января 12, 2014, 00:02 »

но в целом, ответ на вопросе содержался уже в вопросе Улыбающийся

Приходится заводить члены класса, добавлять код рисования рамки в paint и перерисовываться всякий раз при ее изменении.

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

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Января 12, 2014, 11:53 »

и все же... QRubberBand? Улыбающийся
На OSX он просто создает белый виджет с альфой 0.25 (hard-coded). Это все что можно получить

ну, добавится пару строчек кода. проверить, активно ли выделение, и если да, отрисовать прямоугольник. Зачем заморачиваться с какими-то окнами, ксорами...?
Не пару - придется отслеживать mouseMove и.т.п. А резоны такие

1) Тяжелый/длинный paint (доли секунды и больше). Здесь рамочка будет "застревать" (если делать ее в основном paint)

2) Уже имеются какие-то окна (возможно писаные др программистом). Влезать в чужой (развесиситый)  класс, и не один - небольшое удовольствие. Выделять базовый (ради сервиса рамочки) - минимум спорно. Задумка сделать сервис выделения рамкой независимым, чтобы он мог применяться к любому окну. Это ценно/важно

Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #13 : Января 13, 2014, 02:56 »

Независимым, боюсь, не получится. В любом случае ведь придется как-то помечать выделенные объекты. Т.е. они как минимум должны иметь состояние "выделен-не выделен". То есть у всех них видится единый базовый класс, который бы отвечал за статус выделения. И, скорей всего, в зависимости от этого статуса должен меняться их внешний вид, правильно?

Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Января 13, 2014, 11:54 »

Независимым, боюсь, не получится. В любом случае ведь придется как-то помечать выделенные объекты. Т.е. они как минимум должны иметь состояние "выделен-не выделен". То есть у всех них видится единый базовый класс, который бы отвечал за статус выделения. И, скорей всего, в зависимости от этого статуса должен меняться их внешний вид, правильно?
Конечно только само окно знает какие в нем объекты, могут ли они быть выделены и.т.п. Но сначала нужно получить прямоугольник от юзера (т.е. "где выделять"). И тащить этот выбор в каждый или базовый класс совсем не тянет. Хотелось бы напр так
Код
C++ (Qt)
void MyClass::mousePressEvent( QMouseEvent * e )
{
 ...
 QRect selectR;
 if (MyUtils::DoSelectByRect(this, rect(), e->globalPos(), &selectR)) {
   // разбираемся что попало в selectR
 }
...
}
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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