2

I am trying to create a bouding frame for a set of widgets using QFrame.
Eventually, I failed to create a mere empty frame, like demonstrated in Qt documentation (see table in a middle of the page). The QFrame itself is created no problem, but apparently the style fails to apply, and hence the widget is not visible.

styled with .setFrameStyle()

Here is a contrived example code:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QFrame

if __name__ == '__main__':

    app = QApplication(sys.argv)

    window = QWidget()
    window.resize(250, 150)
    window.move(300, 300)
    window.setWindowTitle('Sample')

    window.frame = QFrame(window)
    window.frame.setLineWidth(5)
    window.frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
    # window.frame.setStyleSheet("background-color: rgb(200, 255, 255);"
    #                            "border-width: 1;"
    #                            "border-radius: 3;"
    #                            "border-style: solid;"
    #                            "border-color: rgb(10, 10, 10)"
    #                            )

    window.frame.move(20, 20)
    window.show()

    sys.exit(app.exec_())

If I uncomment .setStyleSheet() call, I get kind of desired effect, but I'm confused with the fact I can't achieve the same thing with .setFrameStyle()

styled with .setStyleSheet()

I am using Python 3.7, PyQt 5.11.3

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
GlebMorgan
  • 37
  • 1
  • 7
  • try with: `app.setStyle("fusion")` – eyllanesc Aug 12 '19 at 11:26
  • That's magic; indeed, widget appearence is entirely controlled by applicaion style. Thank you, `app.setStyle()` works. May I clarify in addition, is it possible to set widget border corner radius not using stylesheets? I just want to be consistent in defining styles (use either method calls or stylesheets). – GlebMorgan Aug 12 '19 at 11:57
  • You can do it but through a QProxyStyle. – eyllanesc Aug 12 '19 at 11:58

2 Answers2

4

It is not a mistake if it is not part of the style you have by default (I suppose it is the "windows" style), in my case I use the "fusion" style and I do not observe the behavior you indicate.

As @ekhumoro points out, StylePanel is a Panel, that is draws a rectangular panel, but respecting the current QStyle. If you want the rectangular panel to be drawn then you must use the QFrame.Panel option instead of QFrame.StylePanel.

window.frame.setFrameStyle(QFrame.Panel | QFrame.Raised)
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • I think it might be the gtk style. The problem is probably the use of `QFrame.StyledPanel`. Using `QFrame.Panel` instead should fix it (it seems to work in qt designer, anyway). – ekhumoro Aug 12 '19 at 13:25
  • @ekhumoro Maybe, unfortunately I can't verify it since I'm not in windows – eyllanesc Aug 12 '19 at 13:29
  • The docs for `StyledPanel` say: "draws a rectangular panel with a look that depends on the current GUI style". It would be very strange having all those other frame options if you could never override the current style. – ekhumoro Aug 12 '19 at 13:35
  • @ekhumoro Yes, I understand what you are saying, but it seems that certain styles such as the one with the OP GUI by default do not implement it. – eyllanesc Aug 12 '19 at 13:38
  • 1
    Sorry, I don't understand you: do not implement what? Some styles like gtk don't draw frame borders by default, but that doesn't mean you can't switch them back on. – ekhumoro Aug 12 '19 at 13:46
  • @ekhumoro 1) I don't think the OP uses it as a GTK style, does that style exist in windows? 2) Of course it is possible to implement the borders, for example through a QProxyStyle, but my only objective in my answer is to point out a possible reason and a workaround – eyllanesc Aug 12 '19 at 13:49
  • I just gave gtk as a known example. But for ***any*** style, if you don't want the default borders drawn by that style (including no borders), then don't use `StyledPanel`. The OP is explicitly adding that option in their example. So all they need to do is replace that option with a different frame-shape, and the borders will be drawn. – ekhumoro Aug 12 '19 at 14:01
  • @ekhumoro I understood you, StylePanel is a Panel dependent on the QStyle. – eyllanesc Aug 12 '19 at 14:03
  • Initially, I didn't set any application style, the default appeared to be 'windowsvista'. All possible options on my Win10 machine are ['windowsvista', 'windows', 'fusion']. – GlebMorgan Aug 12 '19 at 14:20
  • The reason why I used `StyledPanel` is that it goes with those round frame corners. In fact, a better option for me would be to be able to actually control this radius, but without touching `.setStyleSheet()` as it overrides all other style options. I'll try to investigate `QProxyStyle` as you suggested. Is it considered a 'hacky' way of setting style options? – GlebMorgan Aug 12 '19 at 14:20
2
window.frame.setStyleSheet("QFrame {background-color: rgb(200, 255, 255);"
                                "border-width: 1;"
                                "border-radius: 3;"
                                "border-style: solid;"
                                "border-color: rgb(10, 10, 10)}"
                                )
David Buck
  • 3,752
  • 35
  • 31
  • 35