具有透明背景的Qt小部件

9

我正在使用PySide,但我认为任何语言绑定的答案都将是相同/类似的。

我正在尝试采用这里的形状时钟示例,并使时钟面(圆)透明,以便我只看到时钟指针和分钟刻度。目前,当示例运行时,它看起来像这个。我正在使用Windows 7。

到目前为止,我尝试了以下内容(在构造函数中):

  • self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
    • 时钟出现在任务栏中,但我无法在任何地方看到它。
  • self.setAttribute(QtCore.Qt.WA_NoSystemBackground)
    • 时钟出现了,但是有一个纯黑色的背景。
  • self.setWindowOpacity(0.5)
    • 时钟出现了,但整个时钟都是透明的。我希望背景(表盘)是透明的,但是我想让时钟的指针可见。

就记录而言,我认为小部件确实具有透明背景,但显然它正坐在其他不透明的东西上。这是正确的陈述吗? - gdw2
3个回答

12

明白了!

这是来自原始示例代码的部分(构造函数):

    ...
    self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint)
    ...

这是修改后(并且按照我的问题可以正常工作)的版本:

    ...
    self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
    self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
    ...

删除self.windowFlags()是我错过的部分。(我不太确定为什么需要删除它或者为什么一开始会有它...还有很多东西需要学习)。


嗯,我之前没有听说过WA_TranslucentBackground。我尝试将其添加到时钟示例中,并在KDE下运行它,但小部件的背景只是纯黑色。你在代码中还做了什么其他更改,得到了什么结果? - HostileFork says dont trust SE
你有注意到上面的 self.setWindowFlags 行的变化吗? - gdw2
因此,人们应该找出由 self.windowFlags() 默认设置的标志。 - Trilarion

7
如果我没记错的话,您应该也设置了它的样式表:
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.setStyleSheet("background:transparent;")

希望这能有所帮助。

这要视情况而定。小部件本身具有透明背景,因为具有属性QtCore.Qt.WA_TranslucentBackground,不需要其自身的样式表,但包含在小部件内的默认autoFillBackground()==True的子部件应该取消它,或者应该设置QtCore.Qt.WA_TranslucentBackground,或者确实像您所说的那样,应该通过样式表设置透明背景颜色,然后继承它。 - Trilarion
是的,在我的情况下,我需要第三行来设置样式表。因为我正在使用kvantum,而活动主题的样式似乎会覆盖任何非透明背景。但这只是我的假设。 - fsevenm

1
在时钟示例中有:
void ShapedClock::resizeEvent(QResizeEvent * /* event */)
 {
     int side = qMin(width(), height());
     QRegion maskedRegion(width() / 2 - side / 2, height() / 2 - side / 2, side,
                          side, QRegion::Ellipse);
     setMask(maskedRegion);
 }

"setMask"函数可以实现圆形的效果。
但是在PySide中也有相同的功能:

def resizeEvent(self, event):
        side = min(self.width(), self.height())
        maskedRegion = QtGui.QRegion(self.width()/2 - side/2, self.height()/2 - side/2, side, side, QtGui.QRegion.Ellipse)
        self.setMask(maskedRegion)

那么它也应该可以工作吧?


我稍微澄清了一下我的问题。你上面提到的代码确实会使时钟面外的所有东西都变成透明的,但是我想让时钟面本身透明(除了时针和分钟刻度线)。 - gdw2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接