1

I have a QDial widget and I'm wondering if there is a way to disable mouse clicks on the dial. I only want to be able to set the value of the QDial by using setValue(). When a user clicks on the dial, I want nothing to happen instead of moving to the spot where the user clicked. I have looked into mousePressEvent handler, but it still moves the needle to a new location. How can I disable mouse clicks from affecting the value of the QDial? Also: is there a way to change the current value indicator (circle object) into a needle through stylesheets?

from PyQt4 import QtGui, QtCore

class DisabledDial(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.dial = QtGui.QDial()
        self.dial.setMaximum(360)
        self.dial.setNotchesVisible(True)
        self.dial.setWrapping(True)

        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.dial)
        self.setLayout(self.layout)

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.tick_update)
        self.timer.start(1000)

    def tick_update(self):
        self.dial.setValue(self.dial.value() + 10)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    dial = DisabledDial()
    dial.show()
    sys.exit(app.exec_())
4

3 回答 3

2

You have to disable the mousePressEvent(), mouseReleaseEvent() and mouseMoveEvent() methods:

from PyQt4 import QtCore, QtGui


class Dial(QtGui.QDial):
    def mousePressEvent(self, event):
        pass

    def mouseReleaseEvent(self, event):
        pass

    def mouseMoveEvent(self, event):
        pass


class DisabledDial(QtGui.QWidget):
    def __init__(self, parent=None):
        super(DisabledDial, self).__init__(parent)

        self.dial = Dial(
            maximum=360,
            notchesVisible=True,
            wrapping=True,
        )
        lay = QtGui.QVBoxLayout(self)
        lay.addWidget(self.dial)

        timer = QtCore.QTimer(
            self,
            timeout=self.tick_update,
            interval=1000,
        )
        timer.start()

    @QtCore.pyqtSlot()
    def tick_update(self):
        self.dial.setValue(self.dial.value() + 10)


if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    dial = DisabledDial()
    dial.show()
    sys.exit(app.exec_())
于 2019-07-27T04:07:52.157 回答
2

By default, users can control a QDial by using mouse clicks, the mouse wheel, or keyboard shortcuts. To prevent all of these, a simple solution is to use an event-filter, like this:

class DisabledDial(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.dial = QtGui.QDial()
        self.dial.installEventFilter(self)
        ...

    def eventFilter(self, source, event):
        if (source is self.dial and isinstance(event, (
            QtGui.QMouseEvent, QtGui.QWheelEvent, QtGui.QKeyEvent))):
            return True
        return QtGui.QWidget.eventFilter(self, source, event)

As for your other question: at present, there is very little that can be done to change the appearance of a QDial using stylesheets. By default, the shape of the pointer is determined by the widget-style:

enter image description here enter image description here

On my system, the default appearance in PyQt4 looks like the one on the left. But if I use the preview feature in Qt Designer to switch to the "plastique" style, it looks like the one on the right. However, there is no way to change the style for individual widgets - it's a case of all or none. Therefore, the only real solution for altering an individual dial would be to reimplement its paintEvent and use custom drawing to get a different pointer shape. But that is not a straightforward thing to do, so you will need to ask a new question if you want help with that.

于 2019-07-27T11:58:14.870 回答
1

Easier might be to use setEnabled(False), which should prevent user input. However, this also visually disables the dial, which might not look nice.

于 2019-07-27T09:27:07.403 回答