I'm using PyQt4 with Python 2.7 on Windows and for a music player, I decided to replace Phonon.SeekSlider
with a QDial
.
My problem is, that the minimum value of a QDial
is always at the bottom of the dial, but I want it to be at the top (value still increasing clockwise). I tried setInvertedAppearance()
and setInvertedControls()
, but that just flips the dial horizontally and setOrientation()
didn't help either.
My Question: Is there some way to either specify an angle to position the minimum value on the dial or flip the whole dial vertically?
3 Answers
I don't believe there is a way to do this directly. However, you can place the QDial
in a QGraphicsView
, and rotate it as an item in the scene. Something like this should work:
import sys
from PyQt4 import QtGui, QtCore
class RotatableView(QtGui.QGraphicsView):
def __init__(self, item, rotation=0):
QtGui.QGraphicsView.__init__(self)
scene = QtGui.QGraphicsScene(self)
self.setScene(scene)
graphics_item = scene.addWidget(item)
graphics_item.rotate(rotation)
# make the QGraphicsView invisible
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setFixedHeight(item.height())
self.setFixedWidth(item.width())
self.setStyleSheet("border: 0px")
class DialExample(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
dial = QtGui.QDial()
dial.setNotchesVisible(True)
label = QtGui.QLabel('0')
dial.valueChanged.connect(label.setNum)
layout = QtGui.QVBoxLayout()
layout.addWidget(RotatableView(dial, 180))
layout.addWidget(label)
self.setLayout(layout)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dialexample = DialExample()
dialexample.show()
sys.exit(app.exec_())

- 1,279
- 8
- 12
Hackyday give a QgraphicsView
answer, here I give you a pyqt
solution without using QgraphicsView
.
You can do it directly on python with a little if/else
statement.
You create your qDial
, I suppose that you want a dial as a compass (0 - 360°) and I suppose you wrote the output of qDial
on a qSpinBox
):
<widget class="QDial" name="dial">
<property name="geometry">
<rect>
<x>20</x>
<y>150</y>
<width>101</width>
<height>111</height>
</rect>
</property>
<property name="mouseTracking">
<bool>false</bool>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>360</number>
</property>
<property name="singleStep">
<number>0</number>
</property>
<property name="pageStep">
<number>0</number>
</property>
<property name="value">
<number>135</number>
</property>
<property name="sliderPosition">
<number>135</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="invertedControls">
<bool>false</bool>
</property>
<property name="wrapping">
<bool>true</bool>
</property>
<property name="notchesVisible">
<bool>false</bool>
</property>
</widget>
<widget class="QSpinBox" name="oAzimuth">
<property name="geometry">
<rect>
<x>10</x>
<y>110</y>
<width>52</width>
<height>30</height>
</rect>
</property>
<property name="maximum">
<number>360</number>
</property>
<property name="value">
<number>315</number>
</property>
</widget>
If you want to set your default location of slider to 315° so, set it to 135° as in my example. Why ? Because all your degrees between 0° and 180° have to be shift to +180° and the degrees between 181° and 360° to -180°.
So on pyqt
, on your file.py
, you can write and if/else
statement to correct that automatically inside a function
:
def Edit_Slider(self):
if self.dockwidget.spinbox.value() > 180:
self.dockwidget.dial.setValue(self.dockwidget.spinbox.value()-180)
else:
self.dockwidget.dial.setValue(self.dockwidget.spinbox.value()+180)
def Edit_Spinbox(self):
if self.dockwidget.dial.value() > 180:
self.dockwidget.spinbox.setValue(self.dockwidget.dial.value()-180)
else:
self.dockwidget.spinbox.setValue(self.dockwidget.dial.value()+180)
And to edit this change automatically while you moved your slider or your SpinValue :
self.dockwidget.spinbox.valueChanged.connect(self.Edit_Slider)
self.dockwidget.dial.valueChanged.connect(self.Edit_Spinbox)

- 331
- 1
- 2
- 14
-
Maths for converting the value to work correctly being used successfully, thanks! – EM-Creations Jan 22 '18 at 15:27
you also can use qdial value in the linedit.
As the QDial works on Integers only, by using following commands you can use any value in float.
self.dial_object = QtGui.QDial(self.centralwidget)
self.dial_object.setNotchesVisible(True)
self.dial_object.setGeometry(QtCore.QRect(15,110,45,45))
self.dial_object.setMinimum(50)
this sets dial minimum value to .5
self.dial_object.setMaximum(100)
this sets dial maximum value to 1
self.dial_object.setSingleStep(10)
this sets dial resolution value to .01
self.dial_object.setValue(0)
this sets dial starting value to 0
self.dial_object.valueChanged.connect(self.dvalue1)
where
def dvalue1(self):
self.lineEdit_object.setText(str(float(self.dial_object.value())*0.01))
this will change the value into float to string type(used in setText).
0.01 decides the dials resolution.

- 431
- 5
- 11