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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: "Сквозной" дочерний виджет  (Прочитано 5617 раз)
Khs
Гость
« : Март 17, 2009, 08:32 »

Привет! Некоторых спрашивал уже по этому вопросу, но все же.
Имеется: QMainWindow, в его centralWidget установлены QGraphicsView/Scene.
Необходимо: Сделать дополнительный виджет для содержимого сцены (тоесть эдакий управляющий виджет: повернуть, увеличить и тп., такие можно увидеть например в яндекс мапе, или других мап-сервисах). При этом желательно чтобы этот виджет находился внутри геометрии centralWidget (тоесь он буит с парентом), и надо чтобы он был сквозным (тоесть через любую область доп. виджета, кроме его содержимого, можно было "тыкать" в содержимое сцены). Такой эффект для Window достигается флагом Qt::FramelessWindowHint и аттрибутом Qt::WA_TranslucentBackground. А как сделать такой эффект для дочернего окна?
Конечно можно сделать этот доп. виджет внешним, установить данные свойства, и контроллить ресайзы. Так же можно я думаю сделать вырезая регионы контроллов на доп. виджете ручками. Но можно ли как-то сделать как я сначала написал?
Спасибо Улыбающийся
Записан
SABROG
Гость
« Ответ #1 : Март 17, 2009, 09:18 »

Ты забыл уточнить, что тебе это нужно без paintEvent'a.
Записан
drsm
Гость
« Ответ #2 : Март 17, 2009, 11:56 »

я делал через QStackedLayout::StackAll & setMask()

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

hint:
Код
C++ (Qt)
void MegoWidget::updateMask()
{
   QRegion reg(frameGeometry());
   reg -= QRegion(geometry());
   reg += childrenRegion();
   setMask(reg);
}
 
« Последнее редактирование: Март 17, 2009, 12:05 от drsm » Записан
Khs
Гость
« Ответ #3 : Март 18, 2009, 09:23 »

Так понимаю что в чистом виде через аттрибуты для дочернего окна сделать *сквозной* эффект нельзя (хотелось бы знать почему такое не стали делать, видимо суть в заложенной архитектуре взаимодействия виджетов, может кто-нибудь из добрых программистов пояснит? Улыбающийся).

Спасибо за совет с регионами и маской  Улыбающийся
Вот только вопрос. В ассистенте про setMask():
Note that this effect can be slow if the region is particularly complex.
Насколько должен быть сложен регион, чтобы уже были заметны замедления в работе?
Записан
drsm
Гость
« Ответ #4 : Март 18, 2009, 09:41 »

чтобы сделать "сквозной эффект" типа setOpacity() или WA_TranslucentBackground,
виджет должен иметь собственный хендл окна.
тк данные эффекты накладывает композитный window manager.
если же мы накладываем (полу)прозрачность с помощью самой Qt,
то достаточно вполне задать маску и альфа канал в палитре.

по поводу setMask(), у меня работает очень быстро.
правда регионы не сложные совсем.
вызывается оно довольно редко, обычно только при resizeEvent().
накрайняк можно кешировать.

Записан
Khs
Гость
« Ответ #5 : Март 18, 2009, 09:45 »

Вроде понятно, спасибо за пояснения Улыбающийся
Записан
shadone
Гость
« Ответ #6 : Март 18, 2009, 13:22 »

чтобы сделать "сквозной эффект" типа setOpacity() или WA_TranslucentBackground,
виджет должен иметь собственный хендл окна.
тк данные эффекты накладывает композитный window manager.
если же мы накладываем (полу)прозрачность с помощью самой Qt,
то достаточно вполне задать маску и альфа канал в палитре.
нет. Если виджет не является окном то window manager им не управляет и иметь родной хэндл не обязательно.
По поводу (полу)прозрачности абсолютно верно - достаточно указать Qt чем заливать фон виджета. Что-то вроде

Код
C++ (Qt)
QPalette pal = palette();
pal.setBrush(QPalette::Background, QBrush(QColor(255, 0, 0, 127)));
setPalette(pal);
 

по поводу setMask(), у меня работает очень быстро.
правда регионы не сложные совсем.
вызывается оно довольно редко, обычно только при resizeEvent().
накрайняк можно кешировать.
как написано в документации - setMask может быть медленна если используется сложный регион в качестве маски.

log1c: если управляющий виджет не является окном то можно установить ему атрибут Qt::WA_TransparentForMouseEvents - в этом случае нажатие мыши внутри виджета будет передавать родителю (он будет "прозрачным" для событий мыши).
Записан
shadone
Гость
« Ответ #7 : Март 18, 2009, 13:25 »

Спасибо за совет с регионами и маской  Улыбающийся
Вот только вопрос. В ассистенте про setMask():
Note that this effect can be slow if the region is particularly complex.
Насколько должен быть сложен регион, чтобы уже были заметны замедления в работе?
в общем случае это зависит от системы - для top-level windows маска просто передается операционной системе. Для обычных виджетов - насколько сложным должен быть регион можно проверить только экспериментально, не уверен что кто-нибудь замерял производительность в данном случае. По здравому размышлению - большое количество не-прямоугольных регионов - должны быть достаточно сложные (т.к. могут храниться в виде списка прямоугольников).
Записан
drsm
Гость
« Ответ #8 : Март 18, 2009, 16:52 »

чтобы сделать "сквозной эффект" типа setOpacity() или WA_TranslucentBackground,
виджет должен иметь собственный хендл окна.
тк данные эффекты накладывает композитный window manager.
если же мы накладываем (полу)прозрачность с помощью самой Qt,
то достаточно вполне задать маску и альфа канал в палитре.
нет. Если виджет не является окном то window manager им не управляет и иметь родной хэндл не обязательно.
почему нет Веселый?
не понял вобщем с чем ты несогласен.
я имел ввиду, что для того чтобы использовать QWidget::setWindowOpacity() или WA_TranslucentBackground,
виджет должен быть toplevel, те иметь собственных хендл окна.
Записан
shadone
Гость
« Ответ #9 : Март 18, 2009, 17:30 »

нет. Если виджет не является окном то window manager им не управляет и иметь родной хэндл не обязательно.
почему нет Веселый?
уточняю - если виджет не является окном, т.е. не toplevel, то иметь родной хэндл ему не обязательно.

не понял вобщем с чем ты несогласен.
я имел ввиду, что для того чтобы использовать QWidget::setWindowOpacity() или WA_TranslucentBackground,
виджет должен быть toplevel, те иметь собственных хендл окна.
ах, ок тогда. из сообщения было непонятно что имелись ввиду toplevel т.к. хэндлы имеют не только они.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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