Search code examples
qtpyqtpyqt4qdial

PyQt4/Qt: Set orientation of QDial (minimum value at the top)


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?


Solution

  • 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_())