0

I use Nvidia Jetson Nano with Linux for Tegra (Ubuntu 18, X11 window system), Python 3.6 and PyQt5. I want to place a transparent widget (or with a transparent background) over the main widget.

When these widgets are created as independent everything is displayed correctly. Transparency works even if the gstreamer video stream is displayed in the main widget.

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

class MainWindow(QWidget):   
    def __init__(self):
        QWidget.__init__(self)
        self.setGeometry(50,50,320,240)
        self.setWindowTitle("Main Window")
        self.setStyleSheet("background-color:yellow;")
        self.label = QLabel(self)
        self.label.setText("Main Widget")
        self.menu = MenuWidget()
    
class MenuWidget(QWidget):
    def __init__(self): 
        QWidget.__init__(self)
        self.setWindowFlags(Qt.Tool)
        self.setGeometry(100,100,100,50)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet("background-color:gray;")
        self.setWindowOpacity(0.5)
        self.label = QLabel(self)
        self.label.setText("Menu Widget")

app = QApplication([])
window = MainWindow()
window.show()
window.menu.show()
sys.exit(app.exec_())

[enter image description here enter image description here

When I try to create a widget as a child of the main widget, transparency does not work. If a video is displayed, a "hole" appears in the main widget window.

class MainWindow(QWidget):   
    def __init__(self):
        QWidget.__init__(self)
        self.setGeometry(50,50,320,240)
        self.setWindowTitle("Main Window")
        self.setStyleSheet("background-color:yellow;")
        self.label = QLabel(self)
        self.label.setText("Main Widget")
        self.menu = MenuWidget(parent=self)
        print('main window created')
    
class MenuWidget(QWidget):
    def __init__(self, parent): 
        QWidget.__init__(self, parent)
        self.setWindowFlags(Qt.Tool)
        self.setGeometry(100,100,100,50)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet("background-color:gray;")
        self.setWindowOpacity(0.5)
        self.label = QLabel(self)
        self.label.setText("Menu Widget")

app = QApplication([])
window = MainWindow()
window.show()
sys.exit(app.exec_())

enter image description here enter image description here

Also, if I set the attribute self.setAttribute(Qt.WA_TranslucentBackground) for the child widget, a "hole" appears in the main window (if video is playing in this window).

enter image description here

How can transparency be set for a child widget? Thanks in advance for your answers!

lich.mk
  • 71
  • 1
  • 5

2 Answers2

1

As the name suggests, the windowOpacity refers to the opacity of the window.

If you want to set the opacity of a child widget, you need to use QGraphicsOpacityEffect:

class MenuWidget(QWidget):
    def __init__(self, parent): 
        QWidget.__init__(self, parent)
        # ...
        self.setGraphicsEffect(QGraphicsOpacityEffect(opacity=.5))
musicamante
  • 41,230
  • 6
  • 33
  • 58
  • 1
    Thanks for the advice! This method works with a regular window, but does not work with video. The widget is dimmed, but not transparent. – lich.mk Nov 05 '20 at 19:48
  • Mmmh, video overlays makes things trickier. You could try to set a background color with alpha in the stylesheet (`self.setStyleSheet("background-color: rgba(128, 128, 128, 128);"`), but, even assuming it correctly works with the video, that will only make the background semi transparent. – musicamante Nov 05 '20 at 22:20
0

As I understand it, the transparency (background transparency) of the widget can only be created using the desktop compositor. Qt cannot use desktop compositor to render child widgets. The only solution is to use independent windows / widgets. The only solution is to use independent windows/widgets.

lich.mk
  • 71
  • 1
  • 5