Qt - Draw a fully transparent window in Windows without using WA_TranslucentBackground - c++

I need to draw transparent window (either QLabel or QFrame or QWidget), but without using WA_TranslucentBackground. The reason for that is that the windows will contain other child widgets rendered through OpenGL, and using that property makes those windows invisible on Windows, as documented here. This works fine in Mac though, I need a different solution on Windows only, as it does not work there. I tried this: setting a blank pixmap. But it still shows up with a grey background:
#include <QApplication>
#include <QLabel>
#include <QBitmap>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel l;
l.setWindowFlags(Qt::FramelessWindowHint);
QPixmap p("");
l.setPixmap(p);
l.setScaledContents(true);
l.resize(300, 500); //just to test my idea
l.setMask(p.scaled(l.width(),l.height(),Qt::IgnoreAspectRatio,
Qt::SmoothTransformation).mask());
l.show();
return a.exec();
}
Can anyone suggest any other means of achieving this on Windows, i.e a fully transparent window? Platform - Qt 5.3.1, 32 bit.
P.S - It need not behave like translucent window, i.e where the background can be clicked through the transparent parts of a widget rendered though WA_TranslucentBackground. Here as long as it is transparent it will be okay, it need not be clickable 'through'.

I am on Windows (Qt 5) and use the following to create a Semi-Transparent Widget:
setWindowOpacity(0.6);
setStyleSheet("QWidget{background: #000000}")
It should work if you set the opacity to zero.
I use this together with the Windows flags "framelessWindow" and "Tool" to darken the background of the screen.

transparency can be achieved by enabling blur behind window and by setting windows attribute to WA_TranslucentBackground
setAttribute(Qt::WA_TranslucentBackground);
QtWin::enableBlurBehindWindow(this);
required , cpp include : include<QtWin>, project file include : QT += winextras
the method enableBlurBehindWindow() has two more overload ,you can look those on this documentation
For child widgets you can use
setStyleSheet("background:transparent");

Unfortunately this is not possible on Windows. You can set transparency for widget with color with alpha-channel like this: setStyleSheet("background-color: rgba(255,0,0,50%);");. But whis is doesn't work for top level widget until you set WA_TranslucentBackground. Without this flag alpha-channel doesn't work and you get black window. So the only solution is use WA_TranslucentBackground. And then do OpenGL painting like Qt documentation says:
To work around this issue you can either just use Qt to render
everything and not OpenGL, or you can render the OpenGL into a pixmap
and draw that onto your widget instead.

Related

How to hide mouse pointer in Qt app at startup?

I have a small Qt application that displays an image to the screen (more on that including source code here: Qt: Modify alpha channel transparency of a windowless QLabel).
By default, Qt is inserting a mouse pointer on top of my image. For my application, I do not need any physical user interaction with Qt and thus have no need for a mouse pointer.
I have used the following code to hide the mouse pointer, but it only hides the mouse once the mouse has been physically moved, and only within the displayed image. If my image is smaller than the display area, I can freely move the mouse pointer through this space.
int main (int argc, char *argv[])
{
QApplication app(argc, argv);
// Try to hide the cursor
app.setOverrideCursor(QCursor(Qt::BlankCursor));
return app.exec();
}
How can I hide the mouse pointer when I start my application without the need to actually move the mouse?
I am running Qt version 4.8.4 on my embedded deivce.
(Also, I am running my application without a QWidget window. So I am looking for solutions that does not require this).
Try this code :
app.setCursorVisible(false);
or this :
app.setOverrideCursor(Qt::BlankCursor);
I found a command line option, "-nomouse", that seems to do the trick. It is not my ideal solution, but it works for now.
$ ./my-Qt-application -nomouse
http://doc.qt.io/qt-4.8/qt-embedded-running.html (search for -nomouse under the Command Line options)

QT Switching window transparency off

I have following problem. I switched on the transparency of the QWidget (top-level) with
setAttribute(Qt::WA_TranslucentBackground);
and it is all good. The window (QWidget) had a system shadow around it and it dissapeared and it was good as well. However now I need to switch the transparency off and it can be done with:
setAttribute(Qt::WA_TranslucentBackground, false);
But I would like to have the shadow back, but it doesn't appear. I'm using linux. Do you know how to enable the shadow?

Clear Transparent Background for QWidget

I have a widget as on overlay for another widget. The transparency works fine, as long as I don't clear the background of the overlay.
But I have to clear the widget to acutalize the displayed "effects". I tried to solve the inital problem (the background getting the default color) like described in 20848594, but except changing the color to black it had no effect...
Has anyone an idea why the widget which should be transparent does not display the underlaying widget(s)?
Here the code:
SudokuMarkerOverlayWidget::SudokuMarkerOverlayWidget(QWidget* parent, uint const fieldSize) : QWidget(parent)
{
// Translucent should be the correct one
setAttribute(Qt::WA_TranslucentBackground);
//setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_TransparentForMouseEvents);
...
}
void SudokuMarkerOverlayWidget::paintEvent(QPaintEvent*)
{
QPainter painter(this);
painter.setRenderHint( QPainter::Antialiasing );
// Tried this too, no difference
// painter.setCompositionMode(QPainter::CompositionMode_Source);
// painter.fillRect( this->rect(), Qt::transparent );
painter.setCompositionMode(QPainter::CompositionMode_Clear);
painter.eraseRect( this->rect() );
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
...
}
EDIT:
Just noticed, using CompositionMode Source instead of SourceOver for my semi-transparent painting (gradient seen in first image) also causes them to be a red-to-black-gradient instead of red-to-transparent.
That means every transparency except the inital by WA_TranslucentBackground or WA_NoSystemBackground isn't working.
Widgets in Qt can be either a 'native' or 'alien' type. In one case they're a separate operating system window. In some operating systems a transparent window isn't supported.
You might want to consider using QML if you're after fancy visual effects. That's what it was designed for.

How to add the common navigation bar to a Meego app?

When using the Meego Touch Framework, the standard MApplicationWindow has the common navigation bar (with the switcher, menu and close buttons) already attached.
For example, the following code:
#include <MApplication>
#include <MApplicationWindow>
int main(int argc, char *argv[]){
MApplication app(argc, argv);
MApplicationWindow w;
w.show();
return app.exec();
}
Creates a blank window with a menu bar that looks similar to this (eg. the switcher button, menu and close button along the top).
However, since the the docs discourage the use of the Touch Framework I want to avoid using it, so how would I create a similar looking window using only the standard API?
How I would implement this, would probably be a fixed height, variable width QHBoxLayout with a stretch factor for those indices that need it. Then I would just use QPushButton and QCombobBox for the widgets and finish them off with a custom stylesheet and icons. I would then wrap these inside a neat little custom widget that I could reuse in my main view class.
The main view should be a window class that would hold the navigation bar widget on top of a QVBoxLayout, and the actual content below it. The bottom index would have a stretch factor to it, so that the upper index would always be at the top.
I don't quite remember how the Meego handset UX should act like, but that's how I would create a similar looking navigation bar.
I would just go with the QMainWindow class, as this class already has menus, toolbars, statusbar aso.
You should however take care of the orientation switching yourself (I see that the toolbar in portrait mode is at the bottom, while in landscape mode it is on the top).
This could be accomplished by setting the right Qt::ToolbarArea value.
The style of the buttons and the window itself, can be set using a Qt stylesheet.

How can I prevent Gnome from showing two windows when doing alt-tab? (c++ qt app)

(see edits)
I'm developing a QT/c++ application under gnome.
The application a main window and QListBox child window.
Both of these windows show up as separate main windows when I alt-tab away from the application.
How can I make it so that only one window is shown when I (or later the user) uses alt-tab?
I am guessing this behavior comes because one main window doesn't clip the subwindow - the subwindow extends the boundary of the main window. Gnome has bad alt-tab behavior for a number of other applications too, showing modal dialog boxes separately from main windows. But in the case of my app, this is really annoying.
I am thinking I could make a giant transparent window that includes both existing windows. But it would be nicer to find a "clean" solution.
(the most logical guess is indeed that it has something to do with window flags. I've tried every reasonable combination of flags I could think of. The window types are described here)
Edit:
The app has a QWidget as its main window (Not QMainWindow), QListView is contained in the QWidget object and created by passing a point to the main window.
is styled with Qt::Tool | Qt::FramelessWindowHint.
Edit2: The Qt::X11BypassWindowManagerHint style does work to remove the window from the alt-tab list. The problem is that it also makes the window "unmanaged" so it cover the other windows. I could manaully hide whenever I lose focus - prize now for a better solution.
When creating a window for your QListBox window set a Qt::Tool window flag in its constructor or later with setWindowFlags function call. Here is some code snippet(I omitted the headers):
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QMainWindow mw;
mw.show();
QWidget toolWindow(&mw, Qt::Window|Qt::Tool);
QHBoxLayout layout(&toolWindow);
toolWindow.setLayout(&layout);
QListView lv(&toolWindow);
layout.addWidget(&lv);
toolWindow.show();
return app.exec();
}
I've tested this on my Debian sid box (Gnome 2.30, metacity 2.30.1) with freshly created user: .
If this is not what you wanted, then please name the software which works correctly or you may check it yourself. To do this run xprop in terminal window and click on the window you are interested in. The output will contain window flags. The one you are interested in is _NET_WM_WINDOW_TYPE(ATOM). For the tool window(i.e. not listed in alt-tab) this flag is:
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_UTILITY, _NET_WM_WINDOW_TYPE_NORMAL
If the window with these flags is not a toolbox window then something is wrong with your window manager or you have personally set such behavior.
You can try it by hand with the wmctrl tool. With "-r -b SOMETHING" you can modify NET_WM arguments to it. Try these in [1].
If this works, you can add them in with Xlib-Calls (If you get to know X11 Window Number from Qt. I am sure that's possible).
[1] http://standards.freedesktop.org/wm-spec/1.3/ar01s05.html