PyQ中的切换按钮

2024-10-01 17:30:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经在PyQt4中实现了下面的切换按钮,但是我不明白为什么它在“OFF”状态下没有按预期的方式工作。我不明白是什么问题。任何帮助都将是宝贵的和高度赞赏。在

随信附上我的代码。在

from PyQt4.QtCore import QObject
from PyQt4.QtGui import QPen
from PyQt4.QtGui import QBrush
from PyQt4.QtGui import QPalette
from PyQt4.QtGui import QAbstractButton
from PyQt4.QtGui import QPainter
from PyQt4.QtGui import QApplication
from PyQt4.QtCore import QRectF
from PyQt4.QtGui import QLinearGradient, QGradient
from PyQt4.QtCore import QPropertyAnimation
from PyQt4.QtCore import QEasingCurve
from PyQt4.QtCore import Qt, QSize
from PyQt4.QtCore import pyqtProperty, pyqtSlot


class QSlideSwitchPrivate(QObject):

    def __init__(self, q):
        QObject.__init__(self)

        self._position = 0
        self._sliderShape = QRectF()
        self._gradient = QLinearGradient()
        self._gradient.setSpread(QGradient.PadSpread)
        self._qPointer = q

        self.animation = QPropertyAnimation(self)
        self.animation.setTargetObject(self)
        self.animation.setPropertyName("position")
        self.animation.setStartValue(0)
        self.animation.setEndValue(1)
        self.animation.setDuration(300)
        self.animation.setEasingCurve(QEasingCurve.InOutExpo)

    def __del__(self):
        del self.animation

    @pyqtProperty(float)
    def position(self):
        return self._position

    @position.setter
    def position(self, value):
        self._position = value
        self._qPointer.repaint()

    def drawSlider(self, painter):
        margin = 3
        r = self._qPointer.rect().adjusted(0,0,-1,-1)
        dx = (r.width() - self._sliderShape.width()) * self._position
        sliderRect = self._sliderShape.translated(dx, 0)
        painter.setPen(Qt.NoPen)

        # basic settings
        shadow = self._qPointer.palette().color(QPalette.Dark)
        light = self._qPointer.palette().color(QPalette.Light)
        button = self._qPointer.palette().color(QPalette.Button)

        # draw background
        # draw outer background
        self._gradient.setColorAt(0, shadow.darker(130))
        self._gradient.setColorAt(1, light.darker(130))
        self._gradient.setStart(0, r.height())
        self._gradient.setFinalStop(0, 0)
        painter.setBrush(self._gradient)
        painter.drawRoundedRect(r, 15, 15)

        # draw background
        # draw inner background
        self._gradient.setColorAt(0, shadow.darker(140))
        self._gradient.setColorAt(1, light.darker(160))
        self._gradient.setStart(0, 0)
        self._gradient.setFinalStop(0, r.height())
        painter.setBrush(self._gradient)
        painter.drawRoundedRect(r.adjusted(margin, margin, -margin, -margin), 15, 15)

        # draw slider
        self._gradient.setColorAt(0, button.darker(130))
        self._gradient.setColorAt(1, button)

        # draw outer slider
        self._gradient.setStart(0, r.height())
        self._gradient.setFinalStop(0, 0)
        painter.setBrush(self._gradient)
        painter.drawRoundedRect(sliderRect.adjusted(margin, margin, -margin, -margin), 10, 15)

        # draw inner slider
        self._gradient.setStart(0, 0)
        self._gradient.setFinalStop(0, r.height())
        painter.setBrush(self._gradient)
        painter.drawRoundedRect(sliderRect.adjusted(2.5 * margin, 2.5 * margin, -2.5 * margin, - 2.5 * margin), 5, 15)

        # draw text
        if self.animation.state() == QPropertyAnimation.Running:
            return #don't draw any text while animation is running

        font = self._qPointer.font()
        self._gradient.setColorAt(0, light)
        self._gradient.setColorAt(1, shadow)
        self._gradient.setStart(0, r.height() / 2.0 + font.pointSizeF())
        self._gradient.setFinalStop(0, r.height() / 2.0 - font.pointSizeF())
        painter.setFont(font)
        painter.setPen(QPen(QBrush(self._gradient), 0))

        if self._qPointer.isChecked():
            painter.drawText(0, 0, r.width() / 2, r.height()-1, Qt.AlignCenter, "ON")
        else:
            painter.drawText( r.width() / 2, 0, r.width() / 2, r.height() - 1, Qt.AlignCenter, "OFF")

    def updateSliderRect(self, size):
        self._sliderShape.setWidth(size.width() / 2.0)
        self._sliderShape.setHeight(size.height() - 1.0)

    @pyqtSlot(bool, name='animate')
    def animate(self, checked):
        self.animation.setDirection = QPropertyAnimation.Forward if checked else QPropertyAnimation.Backward
        print(self.animation.setDirection)
        self.animation.start()


class QSlideSwitch(QAbstractButton):
    def __init__(self, parent = None):
        super(QAbstractButton, self).__init__(parent)

        self.d_ptr = QSlideSwitchPrivate( self )
        self.clicked.connect( self.d_ptr.animate )
        self.d_ptr.animation.finished.connect( self.update )

    def __del__(self):
        del self.d_ptr

    def sizeHint(self):
        return QSize(48, 28)

    def hitButton(self, point):
        return self.rect().contains(point)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        self.d_ptr.drawSlider(painter)

    def resizeEvent(self, event):
        self.d_ptr.updateSliderRect(event.size())
        self.repaint()


if __name__ == '__main__':

    import sys

    app = QApplication(sys.argv)

    switcher = QSlideSwitch()
    switcher.setCheckable(True)
    switcher.show()

    sys.exit(app.exec_())

Tags: frommarginimportselfdefpositionheightpyqt4
1条回答
网友
1楼 · 发布于 2024-10-01 17:30:53

问题是您没有更改QPropertyAnimation的地址。您不能使用{your QPropertyAnimation}.setDirection = {some value},但使用{your QPropertyAnimation}.setDirection({some value})。你必须换成

@pyqtSlot(bool, name='animate')
def animate(self, checked):
    self.animation.setDirection(QPropertyAnimation.Forward if checked else QPropertyAnimation.Backward)
    self.animation.start()

相关问题 更多 >

    热门问题