1

I have a QDial widget that I want to beautify the circular edge of this widget by adding a QLable as the following figure. However, I think this makes the QLabel the parent widget, and the QDial no further works!

Below is also my simple code.

enter image description here

from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setGeometry(200, 200, 500, 500)
        self.UiComponents()
        self.show()

    def UiComponents(self):
        dial = QDial(self)
        dial.setGeometry(150, 150, 200, 200)

        label_1 = QLabel('', self)
        label_1.move(168, 168)
        label_1.resize(164, 164)
        label_1.setStyleSheet("border: 4px solid gray; border-radius: 82px;")

App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
hamed baghban
  • 25
  • 2
  • 7
  • So, you're using the label to create a bigger border for the dial? That's not a very good idea, for many reasons, but most importantly because if the user has a different style, the result will be terrible, since dial diameters vary from style to style (and from OS to OS). – musicamante Jun 10 '21 at 12:25
  • You are right, but since the border of QDial widget is terrible and it is not possible to change border properties using the stylesheet, I have no other choice! – hamed baghban Jun 10 '21 at 13:55
  • 1
    I can understand your frustration, but consider this: https://i.stack.imgur.com/kSO37.png The first two dials are with breeze and oxygen styles (which are common on linux) and the third with the basic window style. As you can see, none of them is good. If you don't like the look of QDial, then you need to override its `paintEvent` and draw it on your own. – musicamante Jun 10 '21 at 14:06
  • Really grateful for your helpful discussions, could you please introduce a reference or similar sample to learn how to subclass and override the paintEvent()? – hamed baghban Jun 10 '21 at 16:18

1 Answers1

1

The "main" problem is that you're adding the label over the dial, so it won't be able to receive mouse events.

A theoretical solution could be to use label_1.setAttribute(Qt.WA_TransparentForMouseEvents), but that won't be a good idea, for the following reasons:

  1. widget geometries should normally be managed by a layout manager, so you cannot rely on a "guess" done by trial and error: as soon as the window is resized, all geometries will change and you'll end up with a floating circle that will make everything worse;
  2. even assuming you get the positioning right by intercepting the resize event with an event filter, you'd need to manually reset the stylesheet everytime and ensure that it's properly aligned, but that cannot be guaranteed because different size policies and other widgets could change the final radius of the dial;
  3. what you see on your screen is almost never what users will see in theirs, due to lots of reasons including the current OS and QStyle in use; see the following screenshots taken with 3 Qt common styles (Breeze, Oxygen and Windows):

enter image description here

Unfortunately, QDial has never received lots of care from developers, as it's a scarcely used widget that is hard to implement for custom usage. As such, it doesn't support many any appearance features, and there's also no stylesheet configuration.

If you want to change the look of the dial, the only safe possibility is to subclass it, override its paintEvent() and paint it on your own.

musicamante
  • 41,230
  • 6
  • 33
  • 58
  • Thank you so much for your helpful comments, Since I'm not familiar how to subclass and override the paintEvent(), could you please introduce a reference or similar sample to learn it? – hamed baghban Jun 10 '21 at 16:15
  • 1
    @hamedbaghban see this basic implementation: https://gist.github.com/MaurizioB/1d4a10112fbf9b63f035ccea98ff7e29 I suggest you to carefully study it and understand what it does, and search all functions used in the documentation, most importantly those related to [QPainter](https://doc.qt.io/qt-5/qpainter.html). – musicamante Jun 10 '21 at 20:17