PDA

View Full Version : Transparency with QWinWidget



martian
29th June 2009, 22:33
Hi,

I'm trying to make a QWinWidget transparent over the underlying win32 app, so that I can use Qt's QGraphicsView and all the other great UI classes within my application without blocking the underlying apps controls and graphics.

So heres some example code of what I'm trying to do:

Here I have my dll with all the Qt code that I need.



BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved )
{
static bool ownApplication = FALSE;

if ( dwReason == DLL_PROCESS_ATTACH )
ownApplication = QMfcApp::pluginInstance( hInstance );
if ( dwReason == DLL_PROCESS_DETACH && ownApplication )
delete qApp;

return TRUE;
}


extern "C" __declspec(dllexport) bool initGUI( HWND parent )
{
QWinWidget* win = new QWinWidget( parent );
win->setFixedSize(600,200);
win->move(10,10);

QHBoxLayout *hbox = new QHBoxLayout(win);

QLabel *label = new QLabel("QWinWidget -> QLabel");
QLineEdit *edit = new QLineEdit();

hbox->addWidget(label);
hbox->addWidget(edit);

win->show();

return true;
}


initGUI is called from within WinMain of the win32 application which creates a standard black window using CreateWindowEx.



HMODULE mod = LoadLibrary(L"MigrateApplication.dll");

typedef BOOL(*pInitGUI)(HWND parent);
pInitGUI showGUI = (pInitGUI)GetProcAddress( mod, "initGUI" );
if ( showGUI )
showGUI( hWnd );


Now if you look at the attached picture, you will see the QWinWidget's beige background covers the black background of the application. I would like it so that for the Qt Widgets only the QLabel and QLineEdit are viewable and the QWinWidget's background is transparent.

I know Qt::WA_TranslucentBackground can be used for this type of thing, but that requires a frameless window and I need the widget's embedded in the main window.

I may be crazy but I'm looking for any and all possible ways to achieve this, thanks for reading and for any help!

This is for Qt 4.5+, Windows. I have attached the sample applications source.

wysota
29th June 2009, 23:16
Did you try QWidget::setMask()?

martian
30th June 2009, 10:59
Awesome! Thank you! I had played with it a bit, but your post gave me the confidence to keep trying down that path and I got it working :) Hopefully performance won't be too much of an issue.

My next problem is that when drawing text the masking combined with the font's anti-aliasing makes them look quite bad. Any way to have them anti-aliased with a transparent color or the font's main color? Currently the silhouetted edges are using the widgets background for anti-aliasing I believe, creating a white silhouette.

See screen-shots below. The gray is the background of the win32 application.

wysota
30th June 2009, 11:10
Did you try just setting the background role of the widget's palette to Qt::transparent instead of setting the mask?

martian
30th June 2009, 11:23
Yip I've tried that, just sets the widget's background to black as opposed to its standard gray.



QPalette p(win->palette());
p.setColor(QPalette::Background, Qt::transparent);
win->setPalette(p);


The setMask function is working okay for my purposes so far, just need to solve the ugly font rendering.

wysota
30th June 2009, 12:14
It seems that QWinWidget uses some dirty hack to compose the widgets and therefore I don't think you will be able to obtain transparency in the Qt widget. You might try using the translucent background attribute after all, maybe it helps somewhat but apart from that setMask is all you can use.

martian
30th June 2009, 12:24
setMask is working fine, so I will just look into how Qt does the anti-aliasing on fonts and try get the text rendering a bit nicer without the white silhouette.

cuiqimeng
28th February 2015, 07:13
Hi, I'm having exactly the same problem, none of the following ways works for me, any suggestions? Thanks in advance.

QWinWidget* pParentWidget = new QWinWidget(hParent);

1. pParentWidget->setAttribute(Qt::WA_TranslucentBackground, true);
pParentWidget->setWindowFlags(Qt::FramelessWindowHint);

2. pParentWidget->setWindowOpacity(0);

3. QPalette p(pParentWidget->palette());
p.setColor(QPalette::Background, Qt::transparent);
pParentWidget->setPalette(p);

4. setMask isn't suitable for me, as the UI elements are dynamic.(e.g. tree view)