I have a pyqt5 app that sets a Vispy widget as top layer and a QGrapchisView as the bottom layer. I draw a sample line in both canvas with similar geometry.
Problem
Even when setting the rgba with an alpha channel as zero or close to zero, the Vispy canvas widget it is not transparent. I try to make the pyqt5 widget native widget transparent as well but it does not make a transparent background.
Expected behavior
The red line from the QgraphicsView should be viewed in its entirety as as well as the black line in from the Vispy canvas. as well as just see the QGraphicsView background color (white) and not the Vispy background color (rgb(86/255,86/255,86/255) ~ gray)
Code
from PyQt5 import QtWidgets, QtGui, QtCore
from vispy.scene import SceneCanvas, visuals, transforms
import numpy as np
import sys
class VispyCanvasWrapper(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.canvas = SceneCanvas(app='pyqt5', bgcolor=(86 / 255, 86/255, 86/255, 0.1)) # Set the background color to almost transparent
self.grid = self.canvas.central_widget.add_grid()
self.view_vispy = self.grid.add_view(0, 0, bgcolor=(0, 0, 0, 0.1)) # Set the view's background color to almost transparent
self.view_vispy.camera = "panzoom"
self.view_vispy.camera.aspect = 1.0
# Set the parent widget of the canvas.native widget to this widget
self.canvas.native.setParent(self)
self.geometry = QtCore.QRect(0, 0, 500, 500)
self.canvas.native.setGeometry(self.geometry)
# self.canvas.native.setGeometry(self.geometry)
self.setObjectName('background_layer')
# create a transparent background
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setAutoFillBackground(False)
self.this_style_sheet = """
background-color: transparent;
selection-background-color:transparent;
"""
self.setStyleSheet(self.this_style_sheet)
self.canvas.native.setStyleSheet(self.this_style_sheet)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
# apply transparent style sheet
self.this_style_sheet = """
background-color: transparent;
selection-background-color:transparent;
"""
self.transparent_viewport_style_sheet = """
background-color: transparent;
"""
# Geometry of the window
self.geometry = QtCore.QRect(0, 0, 800, 800)
self.scene_rect_value = QtCore.QRectF(0,0, 200, 200)
self.setGeometry(self.geometry)
# Create central widget and layout
central_widget = QtWidgets.QWidget()
layout = QtWidgets.QGridLayout()
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
# Graphics view widget (bottom layer)
self.scene = QtWidgets.QGraphicsScene()
self.graphicsView = QtWidgets.QGraphicsView()
self.graphicsView.setScene(self.scene)
self.graphicsView.setSceneRect(self.scene_rect_value)
layout.addWidget(self.graphicsView, 0, 0)
#vispy widget (top layer)
self.vispy_canvas = VispyCanvasWrapper(self)
layout.addWidget(self.vispy_canvas, 0, 0)
# Dummy line
self.dummy_lines()
def dummy_lines(self):
# add some lines to the line gv
line_list = [[[0, 0], [250,100] ], [[250, 100], [200,-150]]]
pen = QtGui.QPen(QtGui.QColor(255, 0, 0))
for line in line_list:
x1 = line[0][0]
y1 = -line[0][1]
x2 = line[1][0]
y2 = -line[1][1]
line = QtWidgets.QGraphicsLineItem(x1, y1, x2, y2)
line.setPen(pen)
self.scene.addItem(line)
#add line to vispy
line_data = np.array([[[0, 0], [250,100] ], [[250, 100], [200,-150]]])
self.line = visuals.Line(line_data, parent=self.vispy_canvas.view_vispy.scene, color='black')
# Set the zoom extent
self.vispy_canvas.view_vispy.camera.set_range(x=(0, 200), y=(0, 200))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
There are some special properties of
QOpenGLWidgetthat make this tricky, but it should be possible (emphasis mine):So, to take your example (thanks for the well-crafted example!), add
self.canvas.native.setAttribute(QtCore.Qt.WA_AlwaysStackOnTop)in yourVispyCanvasWrapper.__init__. I put it right next to the other settings:On my system this seems to produce the desired results and is hopefully enough to at least get you started: