Gatien G.
Gatien G.

Reputation: 83

Inner shadow effect for QWidget

I'm trying to add an inner shadow effect to some of my widgets:
comparison
I've found the QGraphicsDropShadowEffect Class, but it doesn't seem to exist for inner shadow.
I've seen InnerShadow QML Type too, but I'm not using QML.

Is it actually possible to do without using QML? Maybe using stylesheets?

Upvotes: 2

Views: 3066

Answers (1)

Ted
Ted

Reputation: 523

1. Stylesheet

Unfortunately, in the meanwhile Qt style sheets doesn't support something like "box-shadow" in css. One way to workaround is to use a top and left gradient border to mimic the effect.

border-left: 20px solid black;
border-top: 20px solid black;
border-left-color: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop: 0 rgb(195,195,195), stop: 1 rgb(240, 240, 240));
border-top-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop: 0 rgb(195,195,195), stop: 1 rgb(240, 240, 240));
background-color: rgb(240, 240, 240);

Here is a example using python, however, the stylesheet part is the same for C++ user.

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QGridLayout


class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.resize(600, 400)
        self.widget = QWidget()
        self.widget.setObjectName("w1")
        self.widget2 = QWidget()
        self.widget2.setObjectName("w2")
        self.widget3 = QWidget()
        self.widget3.setObjectName("w3")

        self.label = QLabel("20px")
        self.label2 = QLabel("10px")
        self.label3 = QLabel("3px")

        layout = QGridLayout()
        layout.addWidget(self.label, 0, 0, alignment=Qt.AlignCenter)
        layout.addWidget(self.label2, 0, 1, alignment=Qt.AlignCenter)
        layout.addWidget(self.label3, 0, 2, alignment=Qt.AlignCenter)
        layout.addWidget(self.widget, 1, 0, 3, 1)
        layout.addWidget(self.widget2, 1, 1, 3, 1)
        layout.addWidget(self.widget3, 1, 2, 3, 1)
        layout.setHorizontalSpacing(20)
        self.setLayout(layout)

        self.setStyleSheet("""
                        QWidget{ background-color: rgb(255, 255, 255);}
                        QLabel {font-size: 20px}
                        QWidget#w1 {
                            border-left: 20px solid black;
                            border-top: 20px solid black;
                            border-left-color: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop: 0 rgb(195,195,195), stop: 1 rgb(240, 240, 240));
                            border-top-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop: 0 rgb(195,195,195), stop: 1 rgb(240, 240, 240));
                            background-color: rgb(240, 240, 240);
                            }
                        QWidget#w2 {
                            border-left: 10px solid black;
                            border-top: 10px solid black;
                            border-left-color: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop: 0 rgb(195,195,195), stop: 1 rgb(240, 240, 240));
                            border-top-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop: 0 rgb(195,195,195), stop: 1 rgb(240, 240, 240));
                            background-color: rgb(240, 240, 240);
                            }
                        QWidget#w3 {
                            border-left: 3px solid black;
                            border-top: 3px solid black;
                            border-left-color: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop: 0 rgb(195,195,195), stop: 1 rgb(240, 240, 240));
                            border-top-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop: 0 rgb(195,195,195), stop: 1 rgb(240, 240, 240));
                            background-color: rgb(240, 240, 240);
                            }
                        
                        
                        """)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

enter image description here

2. QFrame

Another way to create a inner shadow is to set QFrame style.

Something like this:

QLabel label(...);
label.setFrameStyle(QFrame::Panel | QFrame::Sunken);
label.setLineWidth(2);
label.setMidLineWidth(1);

Here are some combinations of styles and line widths listed in the document.

enter image description here

Upvotes: 3

Related Questions