PyQt5: создание полупрозрачного окна с непрозрачными детьми

Я хочу создать полноэкранное окно с полупрозрачным фоном, но полностью видимыми дочерними виджетами (вид эффекта наложения).

вот что у меня пока есть:

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_())

это создает полупрозрачный эффект, но даже кнопки полупрозрачные.

Я также попытался заменить

window.setWindowOpacity(0.3)

вызов

window.setAttribute(Qt.WA_TranslucentBackground, True)

но безрезультатно, в этом случае фон был полностью прозрачный (в то время как кнопка была правильно полностью видна).

решение: (реализовано благодаря предложению Аарона):

трюк заключается в реализации пользовательского paintEvent для главного окна.

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_())

1 ответов


Ok, в то время как is, похоже, не работает с доступными флагами, которые вы все еще можете использовать Qt.WA_TranslucentBackground потому что это можно сделать semitranparent вильный на прозрачности.

выведите mainwindow из QMainWindow и используйте этот класс вместо этого.

применить self.setAttribute(Qt.WA_TranslucentBackground, True) к этому классу

реализуйте paintEvent вашего класса mainwindow следующим образом (аналогично, может содержать ошибки, но принцип должен работать):

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)