【发布时间】:2017-04-27 18:24:09
【问题描述】:
我正在 Windows 10 上编写一个桌面应用程序,它执行类似于“共享您的屏幕/应用程序窗口”的操作,并且我遇到了试图突出显示屏幕上感兴趣的区域的经典问题。所以我需要画一个明亮而厚实的矩形,让矩形始终可见且“位于顶部”,并且不会干扰用户输入、鼠标移动等(即所有传递)。
我无法让它与 Qt v5.7 一起正常工作。我要么得到一个带有右边框的不透明窗口(我看不到“下面”的内容),要么得到一个只有黑色 1 像素边框的透明窗口。
我隐约知道,如果我要使用特定于 Windows 的 API,我可以创建一个具有 WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVE 样式等的窗口。
(使用类似“chrome window”的东西 - C# here 中的示例),但除了我还没有尝试过(并且需要在 C++ 而不是 C# 中做)的事实之外,我宁愿用 Qt 来做可能。
案例A我还是Qt的新手,但我认为使用QFrame是可行的方法,所以我写了一些代码:
//
// A- Displays a completely transparent rectangle with a black 1-pixel border.
//
QFrame *frame = new QFrame();
frame->setFrameStyle(QFrame::Box | QFrame::Plain);
frame->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus | Qt::WindowStaysOnTopHint);
frame->setAttribute(Qt::WA_TranslucentBackground, true);
frame->setGeometry(1000,500,600,300); // Just some fixed values to test
frame->show();
这给了我这个,一个带有 1 像素厚黑色边框的矩形:
这很棒,因为矩形始终位于其他所有内容之上,是透明的,可以通过鼠标输入等,无法获得焦点,无法调整大小或移动,并且不会显示在任务栏上。
案例 B 我认为剩下的唯一问题是画一个粗亮的边框,所以我在调用 frame->show() 之前编写了这个代码:
// Set a solid green thick border.
frame->setObjectName("testframe");
frame->setStyleSheet("#testframe {border: 5px solid green;}");
.. 但这确实给了我,呃,什么都没有。 QFrame 根本没有显示!
案例C所以作为测试,我去掉了Qt::WA_TranslucentBackground的设置。代码如下:
//
// C- Displays an opaque pass-through window with a green 5-pixel border.
//
QFrame *frame = new QFrame();
frame->setFrameStyle(QFrame::Box | QFrame::Plain);
frame->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus | Qt::WindowStaysOnTopHint);
// Disabled Qt::WA_TranslucentBackground
//frame->setAttribute(Qt::WA_TranslucentBackground, true);
frame->setGeometry(1000,500,600,300); // Just some fixed values to test
// Set a solid green thick border.
frame->setObjectName("testframe");
frame->setStyleSheet("#testframe {border: 5px solid green;}");
frame->show();
那个窗口仍然是完全通过的,停留在顶部等,并且有右边框,但它当然是不透明的。
现在,事实是:
- 在设置
Qt::WA_TranslucentBackground且不更改样式表的情况下,我得到一个黑色的 1 像素边框/框架; - 设置
Qt::WA_TranslucentBackground并更改样式表,我根本没有边框/框架(窗口变得不可见); -
没有
Qt::WA_TranslucentBackground设置和 更改样式表,我得到了预期的边框/框架;
.. 似乎暗示当窗口透明时,设置了一些样式来获取黑色 1 像素 outside 边框。当我自己更改边框样式时,它完全保留在窗口框架内,因此当窗口透明时消失(案例 B) - 我认为。
有人知道正确的样式表设置应该是什么,这样我才能让窗口完全透明,并带有 5 像素的绿色边框?
此外,我找不到任何文档可以准确地告诉我哪些样式可以应用于什么类型的小部件/窗口(尤其是 QFrame,对于我的测试用例)。这在任何地方都存在吗?知道会很方便,因为我还想为边框使用渐变色,可能还有其他效果。
【问题讨论】:
-
WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVE-- 确认可以工作,而且相当简单。如果抽象层 (Qt) 使某些事情变得过于困难,那么直接使用 Win32 API 来完成任务可能会更好。如果您的应用仅适用于 Windows,则更是如此。 -
我同意,但我首先尝试 Qt(不要介意我的应用程序目前仅适用于 Windows),因为它在我工作的地方被广泛使用,而我的应用程序的其余部分是 Qt(UI 和程序控制)。我的问题可能有一个简单的解决方法,但如果没有,那么我将使用 CreateWindowEx() 等,尽管看起来代码会更长:-)。
-
您可能想看看使用没有父母的
QRubberBand。可能必须使用QWidget::setWindowOpacity,但我认为它会给你一些有用的东西。
标签: c++ qt windows-10-desktop