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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Как сделать фон виджета прозрачным?  (Прочитано 35222 раз)
SOL
Гость
« : Август 04, 2009, 05:39 »

Чтобы добраться до сути моего вопроса, надо рассказать небольшую предысторию.
Началось, собственно, с того, что я поставил на комп Windows 7(Впринципе, выглядит она также как и Vista) Так вот, при включении соответствующей графической опции, все окна в винде становятся прозрачными и слегка размывают фон, находящийся за ними( см. скрин 1 ). Смотрится довольно красиво. Однако разрабы Nero пошли дальше. Как видно из скрина 2, окно программы размывает всё, что находится за самим окном, притом смотрится это эффектно и не нагружает интерфейс. Собственно, такую вот штуку я и хочу провернуть.
Первая мысль была - снести фон виджета. Как не пытался, не получается сделать его прозрачным. Пробывал различные варианты с backgroundRole().
З.Ы. функция setWindowOpacity() не подходит. Она дает совершенно другой эффект - делает всё окно прозрачным, а мне нужно, чтобы такие элементы как кнопки и т.п. оставались непроницаемыми.
« Последнее редактирование: Август 07, 2009, 12:02 от SOL » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #1 : Август 04, 2009, 07:01 »

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

Теперь вопрос: как получить изображение той области над которой находится приложение средствами Qt?   Непонимающий

 

Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
registrationfedser87
Гость
« Ответ #2 : Август 04, 2009, 07:22 »

Посмотри демку qt /demos/deform. Там что-то подобное(линза двигается и увеличивает всё что за ней)
Записан
fuCtor
Гость
« Ответ #3 : Август 04, 2009, 10:22 »

http://wiki.qtcentre.org/index.php?title=ARGB-Widgets посмотрите вот этот пример. Думаю можно что-то почерпнуть из этого.
Записан
SASA
Гость
« Ответ #4 : Август 04, 2009, 12:44 »

Теперь вопрос: как получить изображение той области над которой находится приложение средствами Qt?   Непонимающий

QApplication::desktop()
QWidget::render
QWidget::frameGeometry ()
Записан
MoPDoBoPoT
Гость
« Ответ #5 : Август 04, 2009, 13:12 »

Вот еще по теме: Полупрозрачность. Там далее SABROG рассказывает про атрибут Qt::WA_TranslucentBackground (с примерами), появившийся в Qt, начиная с версии 4.5
Записан
SOL
Гость
« Ответ #6 : Август 04, 2009, 16:53 »

2 shapoclak Хе, ну ты мазахист! Впринципе, такая идея и меня посещала, но зачем самому блюр писать, если в винде он уже предусмотрен, притом там не просто блюр. К нему добавляется эффект падающих лучей, обратите внимание.

2 fedser87 Линза - тоже нето. Она пересисовывала картинку поверх виджета, притом совсем не являясь прозрачной.

2 MoPDoBoPoTА вот это уже теплее, сейчас затестим. Только вот Qt у меня старенький(4.3), надо бы поискать поновее.
Записан
SOL
Гость
« Ответ #7 : Август 04, 2009, 17:41 »

Кстати, вот что заметил. Данная фишка с прозрачностью работает в Nero только под Windows7. Окно этой же версии Nero под виндой XP не прозрачно, поэтому складывается такое впечатление, что предложенный метод тут не сработает. К сожалению, Qt я смогу скачать только ночью, поэтому и результаты позже будут.
Записан
SOL
Гость
« Ответ #8 : Август 05, 2009, 21:13 »

Итак, данные ссылки, конечно, инетесные, но мне не подошли.

В интернете нашел кусок кода на неизвестном мне языке(пишу я под С++)

Код:
class Window(QWidget):
        def __init__(self, *args):
                QWidget.__init__(self, *args)
                self.setLayout(QVBoxLayout())
                self.layout().addWidget(QLabel("This is the text"))

                # let the whole window be a glass
                self.setAttribute(Qt.WA_NoSystemBackground)
                from ctypes import windll, c_int, byref
                windll.dwmapi.DwmExtendFrameIntoClientArea(c_int(self.winId()), byref(c_int(-1)))
        def mousePressEvent(self, event):
                self.repaint()

Код дает вот такой эффект как показано на рисунке: делает весь виджет полупрозрачным и размытым - какраз то, что мне надо.

вот ссылка на тему: http://stackoverflow.com/questions/453069/qt-erase-background-windows-aero-glass
Записан
SOL
Гость
« Ответ #9 : Август 05, 2009, 23:55 »

Хех....что-то глухо тут. Ну ладно. Сутки убил на эту вестч, теперь хотябы всё работает! Тестил под Windows 7 x64, VS2005, Qt v4.3.
Код:
#include <QtGui>
#include <atlbase.h>
#include <uxtheme.h>
void VistaGlass( int * );
int main( int argc, char *argv[] )
{
QApplication a( argc, argv );
QWidget w;
QVBoxLayout *lyt = new QVBoxLayout();
QPushButton *bt = new QPushButton( "Push me!" );
QLabel *lbl = new QLabel( "Yahoo! I was do it!!!" );
lbl->setAlignment( Qt::AlignCenter );
w.setAttribute( Qt::WA_NoSystemBackground );
VistaGlass( ( int* )w.winId() );
w.setLayout( lyt );
w.show();
w.repaint();
w.resize( 300, 450 );
a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
return a.exec();
};

void VistaGlass( int *Handle )
{
HMODULE dwm = ::LoadLibrary( L"dwmapi.dll" );
if(dwm)
{
typedef HRESULT (WINAPI *pDwmExtendFrameIntoClientArea)(HWND, void * MARGINS);
pDwmExtendFrameIntoClientArea procAddr = (pDwmExtendFrameIntoClientArea)::GetProcAddress(dwm, "DwmExtendFrameIntoClientArea");
if(procAddr)
{
MARGINS a = {0,0,1000,0};
HRESULT hr = (procAddr) ((HWND)Handle,&a);
}
::FreeLibrary(dwm);
}
};
Да, и ещё. в библиотеке dwmapi.dll находится ещё куча полезных функций для интерфейса, описание тут :
http://msdn.microsoft.com/ru-ru/magazine/cc163435.aspx
« Последнее редактирование: Август 05, 2009, 23:56 от SOL » Записан
MoPDoBoPoT
Гость
« Ответ #10 : Август 06, 2009, 00:06 »

Это написано на питоне (Python + PyQt).
Этот код будет работать только на компьютере под управлением Windows Vista (или выше), на котором выполняется диспетчер окон рабочего стола (DWM) с включенным эффектом прозрачного стекла.

Цитировать
DwmExtendFrameIntoClientArea является функцией диспетчера окон рабочего стола, которая расширяет фрейм до размера клиентской области. Функция принимает два параметра: дескриптор окна и структуру MARGINS. Структура MARGINS используется для того, чтобы сообщить диспетчеру окон рабочего стола, насколько следует расширить фрейм в клиентской области.

Это не кроссплатформенное решенеие, в общем...
Записан
SOL
Гость
« Ответ #11 : Август 07, 2009, 12:02 »

Хммм....всё оказалось не так хорошо, как я предполагал. При попытке разместить на данном виджете QListView с прозрачным фоном, возник такой вот глюк. То есть программа не перерисовывает то, что находится под viewport 'ом QListView виджета. Для того, чтобы сделать фон в QListView  прозрачным, я использовал давольно варварский метод : viewport()->setAttribute(Qt::WA_NoSystemBackground);
Может кто подскажет, как устранить этот косяк?
Записан
SOL
Гость
« Ответ #12 : Август 09, 2009, 02:01 »

Понял, что QListView тут не при чем. Смеющийся
Когда я пытаюсь перерисовывать любые объекты(изменение текста в QLabel, удаления виджета из лэйаута и т.п.) на прозрачном окне, возникают похожие глюки - старая картинка(виджеты и всё остальное) не затирается, а новая рисуется поверх старой.
Однако, старая картинка исчезает при изменении размеров окна. Собственно, как затереть программно эту тарую картинку?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Август 09, 2009, 13:23 »

Добрый день

С интересом прочитал эту thread и вспомнил что когда-то пытался сделать подобное на Mac платформе. Там с полу/прозрачностью поприятнее, хотя приключений тоже хватает. Дальше экспериментов дело не пошло ввиду:

- неяcно как я буду переносить это с одного framework'а на другой. Например, ну ладно, работает это в Carbon, а что будет в Cocoa? (а переходить прийдется, все равно заставят). Если нужно поддерживать еще и Windows - трудности возрастут многократно.

- такая вещь "будоражит" аппетит пользователя, провоцирует новые UI запросы. Если я не знаю толком какой будет следующий ход в моем "крутом UI" - лучше не начинать.

Но это прекрасная задача для Qt - тянет как минимум на половину новой версии  ;-) Так что имеет смысл написать им feature request, и, может быть, Вас заметят :-)
Записан
SOL
Гость
« Ответ #14 : Август 09, 2009, 14:45 »

Что-то не всё я понял из вышесказанного...
Так всё же, этот баг фиксится, или ждать новой версии? Просто я компилил под Qt 4.3, авось в последней данного бага не будет... осталось только собрать.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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