PyQt5:创建具有非透明子项的半透明窗口 [英] PyQt5: Create semi-transparent window with non-transparent children

查看:330
本文介绍了PyQt5:创建具有非透明子项的半透明窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个带有半透明背景的全屏窗口,但完全可见的子小部件(一种叠加效果).

I want to create a fullscreen window with semitransparent background, but fully visible children widgets (kind of overlay effect).

这是我目前所拥有的:

import sys

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

app = QApplication(sys.argv)

# Create the main window
window = QMainWindow()

window.setWindowOpacity(0.3)
window.setAttribute(Qt.WA_NoSystemBackground, True)
window.setWindowFlags(Qt.FramelessWindowHint)

# Create the button
pushButton = QPushButton(window)
pushButton.setGeometry(QRect(240, 190, 90, 31))
pushButton.setText("Finished")
pushButton.clicked.connect(app.quit)

# Center the button
qr = pushButton.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
pushButton.move(qr.topLeft())

# Run the application
window.showFullScreen()
sys.exit(app.exec_())

这会创建一个半透明的效果,但即使是按钮也是半透明的.

This creates a semi-transparent effect, but even the button is semi-transparent.

我也尝试过替换

window.setWindowOpacity(0.3)

有了这个电话

window.setAttribute(Qt.WA_TranslucentBackground, True)

但无济于事,在这种情况下,背景完全透明(而按钮正确完全可见).

but to no avail, in this case the background was fully transparent (while the button was correctly fully visible).

解决方案:(在 Aaron 的建议下实施):

诀窍在于为主窗口实现一个自定义的paintEvent.

The trick is in implementing a custom paintEvent for the main window.

import sys

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class CustomWindow(QMainWindow):
    def paintEvent(self, event=None):
        painter = QPainter(self)

        painter.setOpacity(0.7)
        painter.setBrush(Qt.white)
        painter.setPen(QPen(Qt.white))   
        painter.drawRect(self.rect())


app = QApplication(sys.argv)

# Create the main window
window = CustomWindow()

window.setWindowFlags(Qt.FramelessWindowHint)
window.setAttribute(Qt.WA_NoSystemBackground, True)
window.setAttribute(Qt.WA_TranslucentBackground, True)

# Create the button
pushButton = QPushButton(window)
pushButton.setGeometry(QRect(240, 190, 90, 31))
pushButton.setText("Finished")
pushButton.clicked.connect(app.quit)

# Center the button
qr = pushButton.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
pushButton.move(qr.topLeft())

# Run the application
window.showFullScreen()
sys.exit(app.exec_())

推荐答案

好吧,虽然似乎不能使用可用的标志,但您仍然可以使用 Qt.WA_TranslucentBackground 因为它可以绘制一个该透明度上的半透明矩形.

Ok, while is seems not to work with the available flags you can still use Qt.WA_TranslucentBackground because it is possible to draw a semitranparent rect on that transparency.

从 QMainWindow 派生主窗口并改用该类.

Derive your mainwindow from QMainWindow and use that class instead.

self.setAttribute(Qt.WA_TranslucentBackground, True) 应用到该类

像这样实现主窗口类的paintEvent(类似,可能包含错误,但原理应该有效):

Implement the paintEvent of your mainwindow class like this (similar, might contain errors, but the principle should work):

QPixmap canvas(rect())

canvas.fill(Qt.transparent) # fill transparent (makes alpha channel available)

QPainter p(canvas)           # draw on the canvas
p.setOpacity(0.3)
p.setBrush(QBrush(Qt.white)) # use the color you like
p.setPen(QPen(Qt.transparen))

p.drawRect(rect()) # draws the canvas with desired opacity

p.start(self)      # now draw on the window itself
p.drawPixmap(rect(), canvas)

这篇关于PyQt5:创建具有非透明子项的半透明窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆