How to create toggle switch button in qt designer?

后端 未结 2 1760
执笔经年
执笔经年 2021-01-06 19:07

I am trying to create toggle button in qt designer. I refer on internet also but i couldn\'t find how to do that. Can anyone know how to do toggle switch button. I have atta

相关标签:
2条回答
  • 2021-01-06 19:34

    Qt Designer to set the position and initialize some properties of the widgets in a window, but it does not work to create widgets with custom painted as the switch so you will have to implement with python. Long ago for a project implement a switch so it will show that code:

    from PyQt5.QtCore import QObject, QSize, QPointF, QPropertyAnimation, QEasingCurve, pyqtProperty, pyqtSlot, Qt
    from PyQt5.QtGui import  QPainter, QPalette, QLinearGradient, QGradient
    from PyQt5.QtWidgets import QAbstractButton, QApplication, QWidget, QHBoxLayout, QLabel
    
    
    class SwitchPrivate(QObject):
        def __init__(self, q, parent=None):
            QObject.__init__(self, parent=parent)
            self.mPointer = q
            self.mPosition = 0.0
            self.mGradient = QLinearGradient()
            self.mGradient.setSpread(QGradient.PadSpread)
    
            self.animation = QPropertyAnimation(self)
            self.animation.setTargetObject(self)
            self.animation.setPropertyName(b'position')
            self.animation.setStartValue(0.0)
            self.animation.setEndValue(1.0)
            self.animation.setDuration(200)
            self.animation.setEasingCurve(QEasingCurve.InOutExpo)
    
            self.animation.finished.connect(self.mPointer.update)
    
        @pyqtProperty(float)
        def position(self):
            return self.mPosition
    
        @position.setter
        def position(self, value):
            self.mPosition = value
            self.mPointer.update()
    
        def draw(self, painter):
            r = self.mPointer.rect()
            margin = r.height()/10
            shadow = self.mPointer.palette().color(QPalette.Dark)
            light = self.mPointer.palette().color(QPalette.Light)
            button = self.mPointer.palette().color(QPalette.Button)
            painter.setPen(Qt.NoPen)
    
            self.mGradient.setColorAt(0, shadow.darker(130))
            self.mGradient.setColorAt(1, light.darker(130))
            self.mGradient.setStart(0, r.height())
            self.mGradient.setFinalStop(0, 0)
            painter.setBrush(self.mGradient)
            painter.drawRoundedRect(r, r.height()/2, r.height()/2)
    
            self.mGradient.setColorAt(0, shadow.darker(140))
            self.mGradient.setColorAt(1, light.darker(160))
            self.mGradient.setStart(0, 0)
            self.mGradient.setFinalStop(0, r.height())
            painter.setBrush(self.mGradient)
            painter.drawRoundedRect(r.adjusted(margin, margin, -margin, -margin), r.height()/2, r.height()/2)
    
            self.mGradient.setColorAt(0, button.darker(130))
            self.mGradient.setColorAt(1, button)
    
            painter.setBrush(self.mGradient)
    
            x = r.height()/2.0 + self.mPosition*(r.width()-r.height())
            painter.drawEllipse(QPointF(x, r.height()/2), r.height()/2-margin, r.height()/2-margin)
    
        @pyqtSlot(bool, name='animate')
        def animate(self, checked):
            self.animation.setDirection(QPropertyAnimation.Forward if checked else QPropertyAnimation.Backward)
            self.animation.start()
    
    
    class Switch(QAbstractButton):
        def __init__(self, parent=None):
            QAbstractButton.__init__(self, parent=parent)
            self.dPtr = SwitchPrivate(self)
            self.setCheckable(True)
            self.clicked.connect(self.dPtr.animate)
    
        def sizeHint(self):
            return QSize(84, 42)
    
        def paintEvent(self, event):
            painter = QPainter(self)
            painter.setRenderHint(QPainter.Antialiasing)
            self.dPtr.draw(painter)
    
        def resizeEvent(self, event):
            self.update()
    
    
    if __name__ == '__main__':
        import sys
        app = QApplication(sys.argv)
        w = Switch()
        w.show()
        sys.exit(app.exec_())
    

    Note: Another possible solution within the Qt world is to use the QML Switch1, 2 component.

    Note: In this post I point out how to add custom widgets to a .ui file.

    0 讨论(0)
  • 2021-01-06 19:46

    A possible solution is to use a stylesheet with a QCheckBox. Just edit the stylesheet for the check box with the following code:

        QCheckBox::indicator:unchecked {
            image: url(switch_off.png);
        }
        QCheckBox::indicator:checked {
            image: url(switch_on.png);
        }
    

    Minimal running example:

    from PyQt5 import QtWidgets
    import sys
    
    app = QtWidgets.QApplication(sys.argv)
    switch = QtWidgets.QCheckBox()
    switch.setStyleSheet('''
        QCheckBox::indicator:unchecked {
            image: url(switch_off.png);
        }
        QCheckBox::indicator:checked {
            image: url(switch_on.png);
        }
    ''')
    switch.show()
    sys.exit(app.exec_())
    

    Unfortunately, this doesn't always work well if you need some resizing and want the checkbox to adjust its appearance.

    The only alternative is to subclass a QPushButton/QAbstractButton (with the checkable() property set to True) and implement the paintEvent on your own, as already suggested by the answer from eyllanesc.

    0 讨论(0)
提交回复
热议问题