PDA

View Full Version : How to make a borderless window staying on the top of the system?



moiit
10th October 2011, 19:38
setWindowFlags(Qt::WindowStaysOnTopHint);
setWindowFlags(Qt::FramelessWindowHint);
Use this, the window is borderless, but it does not stay on top.


setWindowFlags(Qt::FramelessWindowHint);
setWindowFlags(Qt::WindowStaysOnTopHint);
The window stays on top, but it has a border.

Please help, thanks!

wysota
10th October 2011, 19:50
It won't work :) A frameless window is ignored by the window manager. On the other hand the window manager is responsible for honouring (or not) the stays-on-top hint. You can try masking the border out using QWidget::setMask().

moiit
11th October 2011, 09:07
You are almighty.:D
Thanks a lot!

moiit
12th October 2011, 13:30
An extended question:
By using QWidget::setMask(), the frameless window stays on top now.
But how can i make this window translucent?

Thanks.

wysota
12th October 2011, 14:51
Try setting the Qt::WA_TranslucentBackground attribute.

moiit
12th October 2011, 18:09
Thanks for advice!

setStyleSheet("background-color: transparent;");
setAttribute(Qt::WA_TranslucentBackground);
setMask(geometry());
setWindowFlags(Qt::X11BypassWindowManagerHint);
setWindowFlags(Qt::FramelessWindowHint);
setWindowFlags(Qt::WindowStaysOnTopHint);
The window's background is black because Qt::FramelessWindowHint will be ignored.


setStyleSheet("background-color: transparent;");
setAttribute(Qt::WA_TranslucentBackground);
setMask(geometry());
setWindowFlags(Qt::X11BypassWindowManagerHint);
setWindowFlags(Qt::WindowStaysOnTopHint);
setWindowFlags(Qt::FramelessWindowHint);
This way, the window is transparent but it will not stay on top.

I have seen a program that its frameless window is translucent and it can stay on top. That's really cool.

wysota
13th October 2011, 00:01
Why do you want to bypass the window manager and make the window frameless? Isn't setMask enought?

moiit
13th October 2011, 04:44
Why do you want to bypass the window manager and make the window frameless? Isn't setMask enought?
Ok, i delete this row, but problem still there:
First:
setStyleSheet("background-color: transparent;");
setAttribute(Qt::WA_TranslucentBackground);
setMask(geometry());

Next:
To make transparent, it seems Qt::FramelessWindowHint need to be set.
To make stay-on-top, Qt::WindowStaysOnTopHint need to be set.
ie., frameless && stay-on-top && translucent == false.:(
So i guess there must be another method that may solve this issue.

Just tested, for Win7, getting Aero effect is no need Qt::FramelessWindowHint, with stay-on-top working, but it has a Win7 titleBar.
If using setMask(geometry()), the titleBar is removed, with stay-on-top working, but no longer Aero, instead, it becomes translucent.

This means, for Win7, frameless && stay-on-top && translucent == true.:D

Then for other systems, how to?

moiit
13th October 2011, 08:44
Ok, now the question is:
How to make transparent without Qt::FramelessWindowHint to be set? (setWindowOpacity() is not a good idea)

wysota
13th October 2011, 10:00
To make something transparent, set the WA_TranslucentBackground attribute and make sure the widget doesn't paint any background. Don't use stylesheets, they are not needed here. Use only setMask and translucent background. How to remove the background depends on the widget you are using --- surely autoFillBackgorund needs to be set to false and possibly you need to alter QPalette to include transparent brush for the background.

moiit
13th October 2011, 10:49
Thanks for your answer.

setMask(geometry());
setWindowFlags(Qt::WindowStaysOnTopHint);
setAttribute(Qt::WA_TranslucentBackground,true);
setAutoFillBackground(false);
QPalette pal = palette();
pal.setColor(QPalette::Background, QColor (0, 0 , 0, 20));
setPalette(pal);
This won't work. The background is still black.

wysota
13th October 2011, 11:02
This works just fine for me:

#include <QtGui>

class Widget : public QWidget {
public:
Widget() : QWidget() {
setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(windowFlags()|Qt::WindowStaysOnTopH int);
}
protected:
void paintEvent(QPaintEvent *pe) {
QPainter p(this);
p.setBrush(Qt::red);
p.setRenderHint(QPainter::Antialiasing);
p.drawEllipse(rect().adjusted(50,50,-50,-50));
}
void resizeEvent(QResizeEvent *re) {
setMask(rect());
}
};

int main(int argc, char **argv) {
QApplication app(argc, argv);
Widget w;
w.show();
return app.exec();
}

moiit
13th October 2011, 11:09
Thanks for your patience.
My system is win7, when i run your app, the background is black also.

wysota
13th October 2011, 11:14
Tough luck. Maybe you should change the operating system :) And seriously, looks like you'll have to use native (Aero) API.

moiit
13th October 2011, 11:22
:D
Thanks for the quickly reply!
I guess you are using X11. On your system, it works fine.
But i wonder if it is working on mac os & winxp or not.

y.s.bisht
10th November 2011, 19:20
Even I am facing the similar problem, is it resolved?

gouyoku
13th November 2011, 23:24
The original problem of combining two window flags can be solved with:

setWindowFlags(Qt::FramelessWindowHint|Qt::WindowS taysOnTopHint);
The idea is not to overwrite previous flags when settings new ones with each setWindowFlags


Second problem of transparent windows can be solved with:

setAttribute(Qt::WA_TranslucentBackground);
This will not apply to any child widgets, so if you want them to have transparent background you need to set this attribute for each of them.


If you need more transparency you can try:

setStyleSheet("background:transparent;");
but it makes whole program unreadable.
Might be useful for QDeclarativeView tho. This way you can make your whole UI in QML.

Note: works on Windows 7. No idea how it would behave on X11.

Produces a borderless window. The user cannot move or resize a borderless window via the window system. On X11, the result of the flag is dependent on the window manager and its ability to understand Motif and/or NETWM hints. Most existing modern window managers can handle this.

Atomic_Sheep
15th October 2015, 13:59
It won't work :) A frameless window is ignored by the window manager. On the other hand the window manager is responsible for honouring (or not) the stays-on-top hint. You can try masking the border out using QWidget::setMask().

I've got this code:

WidgetTest.pro

QT += core gui

TARGET = WidgetTest

TEMPLATE = app

SOURCES += main.cpp \
mywidget.cpp

HEADERS += \
mywidget.h

mywidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = 0);
~MyWidget();
};

#endif // MYWIDGET_H


mywidget.cpp

#include "mywidget.h"

MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
setWindowFlags( Qt::FramelessWindowHint );
}

MyWidget::~MyWidget()
{
}


main.cpp

#include <QtGui/QApplication>
#include "mywidget.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

MyWidget myWidget;
myWidget.show();

return a.exec();
}

And it pops up with a grey window with no border. How does that work?

anda_skoa
15th October 2015, 14:48
And it pops up with a grey window with no border. How does that work?

Qt::FramelessWindowHint is a request to not have a border.

You set this flag, the windowing system apparently allows it, you get a frameless (no border) window.

Cheers,
_