How to make Qt's window not blocked by windows system menus?
-
I want the label in Figure 1 to display at all times.
The following settings are in the main function and have no effect.w.setWindowFlags( Qt::Window | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Tool);
The Windows menu in Figure 2 is blocked, so I am looking for a way to avoid being blocked. Thank you.
-
@yolo13
Could you please post your code? -
@Axel-Spoerl This is in the main function
#include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus | Qt::Tool); w.setAttribute(Qt::WA_TranslucentBackground); w.showFullScreen(); w.show(); return a.exec(); }
WindowStaysOnTopHint has been set, but it cannot prevent it from being blocked by the Windows menu .
-
@yolo13
What does "being blocked" mean? What is prevented from happening by what?The OP title says:
How to make Qt's window not blocked by windows system menus?
The text on the second image says:
The Windows menu in Figure 2 is blocked
=> If the problem is, that the Windows menu is blocking: What is it blocking?
=> If the problem is, that the Windows menu is being blocked, that's because it the widget stays on top. -
@Axel-Spoerl Thank you for your answer. I think I may not have described it clearly. What I mean is that the window opened by Qt is blocked by the Windows menu
-
@yolo13
Ok.
If you want others to fully understand (and solve) your problem, please be specific, clear and complete. I'll repeat the questions, that you have not answered:- What does "being blocked" exactly mean? Is it not / partly visible, because it's overlapped? Does it not react to input? Is the mouse cursor hiding behind it?
- Please show your code. You have shared
main.cpp
, but not the implementation ofWidget
- In addition: What's the red rectangle on the second picture? Is it the the widget? Or is it a rectangle manually added in the screenshot to point to something?
-
@Axel-Spoerl Sorry, this is my first time asking a question on the forum. I apologize for the confusion caused by my unclear description. I am using translation software to communicate, I'm sorry. Here are my responses:
-
"Being blocked" means that it is not visible due to overlapping.
-
widget.cpp
#include "widget.h" #include "ui_widget.h" #include "keymonitor.h" #include "capturer.h" #include <QIcon> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); this->setWindowIcon(QIcon("://image/logo.ico")); ui->label->hide(); mic_init(); screenWidth = GetSystemMetrics(SM_CXSCREEN); screenHeight = GetSystemMetrics(SM_CYSCREEN); //键盘事件触发connect+ connect( KeyCapturer::instance(), &KeyCapturer::getKey, [=](int key){ if( key == 1 ){//麦克风CTRL+ALT+O mic_mode(); }if( key == 2 ){//大小写 aA_mode(); }if( key == 3 ){//小键盘锁定 numlock_mode(); }if( key == 4 ){//触摸盘CTRL+F5 + 判断触摸盘是否被锁定 touchpad_mode(); }if( key == 5 ){//工作模式切换CTRL+1 work_mode(); }}); startHook(); } Widget::~Widget() { delete ui; endpointVolume->Release(); defaultDevice->Release(); deviceEnumerator->Release(); } void Widget::mic_init() { //遍历设备初始化麦克风 CoInitialize(NULL); CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (LPVOID*)&deviceEnumerator); deviceEnumerator->GetDefaultAudioEndpoint(eCapture, eConsole, &defaultDevice); defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (LPVOID*)&endpointVolume); } void Widget::mic_mode() { QPropertyAnimation *m_animation_mic = new QPropertyAnimation; set_animation(m_animation_mic); if (flag_mic == 0) { UnmuteMicrophone(); icon_path = "://image/mic2.png"; this->set_icon(icon_path); m_animation_mic->start(); flag_mic = 1; }else { MuteMicrophone(); icon_path = "://image/mic1.png"; this->set_icon(icon_path); m_animation_mic->start(); flag_mic = 0; } } void Widget::aA_mode() { QPropertyAnimation *m_animation_A = new QPropertyAnimation; set_animation(m_animation_A); if (isCapsLockOn()) { icon_path = "://image/a.png"; this->set_icon(icon_path); Sleep(1); m_animation_A->start(); }else { icon_path = "://image/a1.png"; this->set_icon(icon_path); m_animation_A->start(); } } void Widget::numlock_mode() { QPropertyAnimation *m_animation_1 = new QPropertyAnimation; set_animation(m_animation_1); if (isNumLockOn()) { icon_path = "://image/num2.png"; this->set_icon(icon_path); m_animation_1->start(); }else { icon_path = "://image/num1.png"; this->set_icon(icon_path); m_animation_1->start(); } } void Widget::touchpad_mode() { QPropertyAnimation *m_animation_touch = new QPropertyAnimation; set_animation(m_animation_touch); if (flag_touch == 0) { icon_path = "://image/touch1.png"; this->set_icon(icon_path); flag_touch = 1; m_animation_touch->start(); }else { icon_path = "://image/touch2.png"; this->set_icon(icon_path); flag_touch = 0; m_animation_touch->start(); } } void Widget::work_mode() { QPropertyAnimation *m_animation_work = new QPropertyAnimation; set_animation(m_animation_work); if (flag_work == 0) { icon_path = "://image/quite.png"; this->set_icon(icon_path); flag_work = 1; m_animation_work->start(); } else if (flag_work == 1) { icon_path = "://image/pingheng.png"; this->set_icon(icon_path); flag_work = 2; m_animation_work->start(); } else if (flag_work == 2) { icon_path = "://image/xingneng.png"; this->set_icon(icon_path); flag_work = 3; m_animation_work->start(); } else if (flag_work == 3) { icon_path = "://image/mad.png"; this->set_icon(icon_path); flag_work = 0; m_animation_work->start(); } } void Widget::set_icon(QString icon) { QImage image(icon); ui->label->setPixmap(QPixmap::fromImage(image)); ui->label->setGeometry( (screenWidth / 2) - (image.width() / 2) , (screenHeight / 3) * 2, image.width(), image.height() ); //ui->label->setFixedSize(image.size()); ui->label->show(); } void Widget::MuteMicrophone() { endpointVolume->SetMute(TRUE, NULL); } void Widget::UnmuteMicrophone() { endpointVolume->SetMute(FALSE, NULL); } bool Widget::isCapsLockOn() { return (GetKeyState(VK_CAPITAL) & 0x0001) != 0; } bool Widget::isNumLockOn() { return (GetKeyState(VK_NUMLOCK) & 0x0001) != 0; } void Widget::set_animation(QPropertyAnimation *an) { an->setTargetObject(this); //设置使用动画的控件 an->setEasingCurve(QEasingCurve::Linear); //设置动画做的事情Opacity透明度 an->setPropertyName("windowOpacity"); //设置动画时间 an->setDuration(1500); //设置动画步长值,以及在该帧数位置时显示的透明度 an->setKeyValueAt(0, 0.8); an->setKeyValueAt(0.066, 0.8); an->setKeyValueAt(0.132, 0.8); an->setKeyValueAt(0.198, 0.8); an->setKeyValueAt(0.264, 0.8); an->setKeyValueAt(0.33, 0.8); an->setKeyValueAt(0.396, 0.8); an->setKeyValueAt(0.462, 0.8); an->setKeyValueAt(0.528, 0.8); an->setKeyValueAt(0.594, 0.8); an->setKeyValueAt(0.594, 0.8); an->setKeyValueAt(0.66, 0.8); an->setKeyValueAt(0.726, 0.7); an->setKeyValueAt(0.766, 0.65); an->setKeyValueAt(0.792, 0.6); an->setKeyValueAt(0.825, 0.55); an->setKeyValueAt(0.858, 0.5); an->setKeyValueAt(0.891, 0.4); an->setKeyValueAt(0.924, 0.3); an->setKeyValueAt(0.957, 0.2); an->setKeyValueAt(0.99, 0.1); an->setKeyValueAt(1, 0); }
-
The red rectangle is an image edited in my screenshot.
-
Now, what I would like to ask is whether there is a method in Qt that can give the Qt window the highest priority, so that it is not overlapped by the Windows menu and remains visible.
Thank you for your patience.
-
-
@yolo13
Thanks for the clarification, now I understand the intention. I know that the red rectangle is a marker, notWidget
.As the name indicates,
Qt::WindowStaysOnTopHint
is a hint. It says that the window wants to stay on top. But it doesn't guarantee, that this is always the case. Launching the Windows menu, accessing icons on the footer or switching to the task manager - these are the only ways to force an application to quit, if it hangs for instance. A window staying always on top deprives users of the option to control their desktop. Qt applications accept hide and show events, triggered by the window manager in order to accept its superiority.If you want to change that behaviour and force staying on top, you have to override
Object::event()
in Widget, interceptQEvent::Type::Hide
, ignore the event and callQWidget::show()
instead.
You may want to implement a localWidget::hide()
slot, that disables theHide
interception and actually hides the widget.To override the Windows menu and the task bar, you may have to experiment with
FocusOut
or other events. JustqDebug()
the event type and see what happens whenWidget
gets overlapped. -
Hi,
I'm not sure this gets you exactly what you need, but you could try Qt::BypassWindowManagerHint, which says:
This flag can be used to indicate to the platform plugin that "all" window manager protocols should be disabled. This flag will behave different depending on what operating system the application is running on and what window manager is running. The flag can be used to get a native window with no configuration set.
I tried it on X11 and it seems to achieve the result you're looking for.
-
@Axel-Spoerl
Thank you, I have resolved the issue by setting up uiAccess
-