qt qwidget或qframe界面如何实现某个区域透明,例如三层widget,最上层的widget某个区域可以透过第二层和第三层直接看到桌面
4条回答 默认 最新
关注【相关推荐】
- 你可以看下这个问题的回答https://ask.csdn.net/questions/7503607
- 你也可以参考下这篇文章:QT widget提升为自己定义的widget,Qwidget封装并嵌套使用
- 同时,你还可以查看手册:qt QWidget 中的内容
- 您还可以看一下 明仕强老师的Qt高级开发视频教程课程中的 QWidget类详细介绍小节, 巩固相关知识点
- 除此之外, 这篇博客: Qt在透明QWidget上自由绘画中的 如何让QWidget变透明 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
先说一下被误导的尝试,关于让窗体透明,网友办法很多。
setWindowOpacity(0) ;:设置完之后,窗体不会有任何显示,就像你从来没运行过程序一样。除了特殊用途,一般也不会有这种需求。setPalette(palette): 其中palette给一个透明的图片当背景,或者透明的颜色值。错误,设置完后,窗体会变成黑色。- …不一一列举了…
进入整体,其实透明窗体实现相对简单,对你想要透明的QWidget对象设置三个属性就行了(构造函数还是main函数中设置,看你心情)。伪代码如下:
setWindowFlags(Qt::FramelessWindowHint); setAttribute(Qt::WA_NoSystemBackground); setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_TransparentForMouseEvents);稍微解释一下:
-
Qt::FramelessWindowHint:
Produces a borderless window. The user cannot move or resize a borderless window via the window system.
产生一个无边框的窗体。用户无法通过窗体系统移动窗体或者改变窗体的大小。
上面是Qt帮助文档中关于FramelessWindowHint标签的解释,该说的都说明了。需要关注的是,用户无法通过普通的方式改变窗体的大小和位置了。
-
Qt::WA_NoSystemBackground:
Indicates that the widget has no background.
表明指定的widget没有背景。
而默认的QWidget通常会自带一个白色的背景。计算机中,对于颜色,没有的意思一般都是黑色。例如,RGB值为0,0,0时。eum~有点懵,为啥要设置这个??不纠结
-
Qt::WA_TranslucentBackground:
Indicates that the widget should have a translucent background, i.e., any non-opaque regions of the widgets will be translucent because the widget will have an alpha channel. Setting this flag causes WA_NoSystemBackground to be set.
表明widget应该具有半透明的背景,即任何不透明的区域都将是半透明的。设置这个标签将导致
Qt::WA_NoSystemBackground被同时设置。嗯~~不透明的区域半透明!!!什么鬼话。翻译一下,大概就是,应该透明的地方透明,不应该透明的地方不透明,例如:没有任何控件的地方就是应该透明的,有子
QWidget或者QPainter画出的线条的地方就不是透明的。还有一点挺有意思的,这个标签被设置后,
Qt::WA_NoSystemBackground也会被设置,所以其实伪代码中的setAttribute(Qt::WA_NoSystemBackground);是可以省略的。 -
Qt::WA_TransparentForMouseEvents:
When enabled, this attribute disables the delivery of mouse events to the widget and its children.
启用该属性时,将禁止想widget和它的子widget传递鼠标事件。
这个属性后面会用,顺便在这里解释先。
最后,来看一下每个属性的效果,我的工程主窗体就是一个普通的
QWidget,方便起见,显示了一个Label,并重写了paintEvent函数,使用QPainter画了一个椭圆。源码会在文末附上。
上面是什么属性都没有设置的
QWidget,蓝色文字部分是一个Label,红色的椭圆是用QPainter画在QWidget上的。我们要达到的透明效果是,只能看到蓝色文字和红色椭圆,其它都是桌面背景。下面通过属性的一步步设置,仔细观察一下界面的变化吧。
上面是
setWindowFlags(Qt::FramelessWindowHint);代码执行后的界面。QWidget的标题框消失了,但是还有默认背景。
上面是setAttribute(Qt::WA_NoSystemBackground);执行后的界面,还真的变黑了。不纠结
当当当~,这不就是我要的效果么。这是执行了
setAttribute(Qt::WA_TranslucentBackground);的效果。背景其实就是我的桌面背景。接下来一个问题就是,当
QWidget变成透明背景后,居然没法响应鼠标了,鼠标的事件没有发给我的widget。来看看效果:

途中的
Lable的拖动效果,是因为我重写了QWidget的mouseMoveEvent和mousePressEvent函数。代码大概是这样的:void Widget::mousePressEvent(QMouseEvent *event) { mousePosition = event->globalPos(); } void Widget::mouseMoveEvent(QMouseEvent *event) { const QPoint position = pos() + event->globalPos() - mousePosition; move(position.x(), position.y()); mousePosition = event->globalPos(); }只有鼠标在
Label上时,widget才能够响应鼠标的拖拽动作,在QPainter画出的红色椭圆上,鼠标的效果和在桌面的效果没啥区别。无法效应鼠标,肯定就不能作画,毕竟我们的手绘是需要靠鼠标或者触控笔输入的。那么,怎么让透明的窗体相应鼠标的各种事件呢?
如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^解决 无用评论 打赏 举报