PySide2 – Widget above a widget with a shadow effect moves under the second

Question:

I am writing a virtual keyboard for an app that will be using with touch screen.
If you wanna ask me, why i don’t use pyqt virtual keyboard, i’ll answer that my keyboard must have some additional buttons and function.

My keyboard is a class, that draws each button when it called(show_keyboard). It has a parent widget that has a slightly transparent background(0.95) and contains the main widget(QVBoxLayout) which contains the layout of each row with character buttons (1,2,3,4,5,6…; q,w,e,r,t,y…; a, s,d,f,g…; z,x,c,v,b,n…) and functional buttons.

Problem is: when i show this keyboard above widget that has a shadow effect, it moves main widget of the keyboard under the widget with shadow.

there is a similar situation in code:

class MyMainWindow(QMainWindow):
    def __init__(self):
        super(MyMainWindow, self).__init__()

        central_widget = QWidget(self)
        central_layout = QVBoxLayout()
        central_widget.setLayout(central_layout)
        central_widget.layout().setAlignment(Qt.AlignBottom)

        self.setCentralWidget(central_widget)

        self.under_widget_with_shadow = QWidget()
        self.under_widget_with_shadow.setStyleSheet("background-color: gray")
        self.under_widget_with_shadow.setFixedSize(QSize(
            QGuiApplication.primaryScreen().size().width(),
            200
        ))
        # shadow effect
        under_widget_shadow_effect = QGraphicsDropShadowEffect(self)
        under_widget_shadow_effect.setBlurRadius(15)
        under_widget_shadow_effect.setOffset(-3, -3)
        under_widget_shadow_effect.setColor(QColor(200, 0, 0))
        under_widget_shadow_effect.setEnabled(True)
        self.under_widget_with_shadow.setGraphicsEffect(under_widget_shadow_effect)

        self.under_widget_without_shadow = QWidget()
        self.under_widget_without_shadow.setStyleSheet("background-color: gray")
        self.under_widget_without_shadow.setFixedSize(QSize(
            QGuiApplication.primaryScreen().size().width(),
            200,
        ))

        self.above_widget = QWidget(self)
        self.above_widget.setStyleSheet("background-color: lightgray")
        above_layout = QVBoxLayout()
        self.above_widget.setLayout(above_layout)
        self.above_widget.setGeometry(QRect(
            0, QGuiApplication.primaryScreen().size().height() - 500,
            QGuiApplication.primaryScreen().size().width(), 500,
        ))

        for char in ['A', 'B', 'C', 'D']:
            row_widget = QWidget()
            row_layout = QHBoxLayout()
            row_widget.setLayout(row_layout)
            for i in range(1, 12):
                btn = QPushButton()
                btn.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
                btn.setText(f"{char}{i}")
                row_layout.addWidget(btn)
            above_layout.addWidget(row_widget)

        central_layout.addWidget(self.under_widget_without_shadow)
        central_layout.addWidget(self.under_widget_with_shadow)


if __name__ == '__main__':
    app = QApplication()
    window = MyMainWindow()
    window.showFullScreen()
    exit(app.exec_())

image of the BUG

When i removed shadow effect from widget it works normally.

Asked By: vladik

||

Answers:

Solved the problem by adding a shadow effect to the keyboard parent frame.

self.above_widget.setGraphicsEffect(QGraphicsDropShadowEffect(self))
Answered By: vladik
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.