Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to customise QGroupBox title in PyQt5?

Tags:

python

css

pyqt5

Here's a piece of code that creates a simple QGroupBox:

from PyQt5.QtWidgets import (QApplication, QWidget,
                             QGroupBox, QGridLayout)

class QGroupBoxTest(QWidget):
  def __init__(self):
    super().__init__()
    self.initUI()

  def initUI(self):
    gb = QGroupBox()
    gb.setTitle('QGroupBox title')

    appLayout = QGridLayout()
    appLayout.addWidget(gb, 0, 0)
    self.setLayout(appLayout)

    self.setWindowTitle('QGroupBox test window')
    self.setGeometry(300, 300, 300, 200)

if __name__ == "__main__":

  import sys

  app = QApplication(sys.argv)
  test = QGroupBoxTest()
  test.show()

  sys.exit(app.exec_())

and here's what the output looks like to me:

qgb-1.jpg

Now let's say I want to add some style to it and I do this by adding this line to the initUI method:

gb.setStyleSheet("border: 1px solid gray; border-radius: 5px")

here's the output:

qgb-1.jpg

As can be clearly seen from the pic, the title has ended up inside the frame and now is overlapping the frame border.

So I have three questions actually:

  1. Why did the title move?
  2. How do I move it about and place it wherever I want (if possible)?
  3. What if I simply want to round off border corners without specifying the border-style property. Let's say I want the border-style to stay the same as in the first pic but with rounded corners. How do I do that?
like image 675
weeCoder Avatar asked Sep 19 '25 08:09

weeCoder


2 Answers

1) Probably that's the default QT placement, in the first image the platform style is used, and its take care of borders and title placement, when you change the stylesheet you override something and you get the ugly placement.

2) You can control the "title" position using the QGroupBox:title controls, for example:

gb.setStyleSheet('QGroupBox:title {'
                 'subcontrol-origin: margin;'
                 'subcontrol-position: top center;'
                 'padding-left: 10px;'
                 'padding-right: 10px; }')

will result in something like this:

title

3) My suggestion is to create different strings for the stylesheet attributes you want to change, then compose them to create the style you want.

like image 131
Ceppo93 Avatar answered Sep 20 '25 21:09

Ceppo93


Even though this question has already been answered, I will post what I've figured out regarding technics of applying style sheets to widgets in PyQt which partly answers my original question. I hope someone will find it useful.

I think it's nice to keep the styles in separate css(qss) files:

/*css stylesheet file that contains all the style information*/

QGroupBox {
  border: 1px solid black;
  border-radius: 5px;
}

QGroupBox:title{
  subcontrol-origin: margin;
  subcontrol-position: top center;
  padding: 0 3px 0 3px;
}

and the python code looks like this:

from PyQt5.QtWidgets import (QApplication, QWidget,
                             QGroupBox, QGridLayout)
from PyQt5.QtCore import QFile, QTextStream

class QGroupBoxTest(QWidget):
  def __init__(self):
    super().__init__()
    self.initUI()

  def initUI(self):
    gb = QGroupBox()
    gb.setTitle('QGroupBox title:')

    gb.setStyleSheet(self.getStyleSheet("./styles.qss"))

    appLayout = QGridLayout()
    appLayout.addWidget(gb, 0, 0)
    self.setLayout(appLayout)

    self.setWindowTitle('QGroupBox test window')
    self.setGeometry(300, 300, 300, 300)

  def getStyleSheet(self, path):
    f = QFile(path)
    f.open(QFile.ReadOnly | QFile.Text)
    stylesheet = QTextStream(f).readAll()
    f.close()
    return stylesheet

if __name__ == "__main__":

  import sys

  app = QApplication(sys.argv)
  test = QGroupBoxTest()
  test.show()

  sys.exit(app.exec_())

which yields the following output:

qgb-1.jpg

like image 28
weeCoder Avatar answered Sep 20 '25 22:09

weeCoder