鼠标点击穿透,即所有鼠标键盘操作全部会穿透窗口到下方窗口。在Linux下,Qt的Qt::WA_TransparentForMouseEvents属性可以对子部件实现鼠标穿透,但是对整个窗口不行,要想在Linux下对Qt的整个窗口设置鼠标穿透,这时候可以用到X11中x11shape的XShapeCombineRectangles()库函数,很多窗口挂件都是这样做的,如osd桌面歌词程序等等。示例代码编写了一个简单的桌面水印,在桌面的右下方显示了一张图片和一段文字描述,在设置了鼠标点击穿透的情况下用鼠标点击该水印,是可以直接穿透该水印的。
示例源码
开发库的安装
$ sudo apt install qtbase5-dev qt5-qmake qtchooser qtscript5-dev qttools5-dev-tools qtbase5-dev-tools libqt5x11extras5-dev libx11-dev libxext-dev
示例源码的编译和运行
1 | $ qmake |
XShapeCombineRectangles库函数参数分析
1 | void XShapeCombineRectangles ( |
在设置鼠标穿透的时候给函数传的第六个参数为NULL(参数为XRectangle*类型),那整个窗口都将被穿透,第七个参数就是控制设置穿透的,为0时表示设置鼠标穿透,为1时表示取消鼠标穿透,当取消设置鼠标穿透的时候,必须设置区域,即第六个参数不再为NULL(当第6个参数XRectangle的x,y,width和height都为0,且第七个参数设置为1时,也表示设置为鼠标穿透)。
示例代码分析要点
在Qt的.pro文件中,需要注意如下三行,即链接x11和xext库。
1
2
3QT += x11extras
CONFIG += link_pkgconfig
PKGCONFIG += x11 xext设置鼠标穿透
头文件 X11/extensions/shape.h 来自于libxext-dev包。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <QtX11Extras/QX11Info>
#include <X11/extensions/shape.h>
void Utils::passInputEvent(int wid)
{
XRectangle *reponseArea = new XRectangle;
reponseArea->x = 0;
reponseArea->y = 0;
reponseArea->width = 0;
reponseArea->height = 0;
//XShapeCombineRectangles(QX11Info::display(), wid, ShapeInput, 0, 0, reponseArea ,1 ,ShapeSet, YXBanded);
XShapeCombineRectangles(QX11Info::display(), wid, ShapeInput, 0, 0, NULL, 0, ShapeSet, YXBanded);
delete reponseArea;
}取消鼠标穿透
1
2
3
4
5
6
7
8
9
10
11
12void Utils::unPassInputEvent(int wid, QSize size)
{
XRectangle *reponseArea = new XRectangle;
reponseArea->x = 0;
reponseArea->y = 0;
reponseArea->width = size.width();
reponseArea->height = size.height();
XShapeCombineRectangles(QX11Info::display(), wid, ShapeInput, 0, 0, reponseArea ,1 ,ShapeSet, YXBanded);
delete reponseArea;
}