I want to create a fullscreen window with semitransparent background, but fully visible children widgets (kind of overlay effect).
Here's what I have so far:
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.
I also tried to substitute the
window.setWindowOpacity(0.3)
with this call
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).
Solution: (implemented thanks to Aaron's suggestion):
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_())
Best Answer
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.Derive your mainwindow from QMainWindow and use that class instead.
Apply
self.setAttribute(Qt.WA_TranslucentBackground, True)
to that classImplement the paintEvent of your mainwindow class like this (similar, might contain errors, but the principle should work):