Python 如何在qt设计器中创建切换开关按钮?

Python 如何在qt设计器中创建切换开关按钮?,python,pyqt,pyqt5,qt-designer,Python,Pyqt,Pyqt5,Qt Designer,我正在尝试在qt设计器中创建切换按钮。我也在网上查过,但我找不到怎么做。任何人都知道如何做切换开关按钮。我附上了一个样本按钮图像 编辑 我在下面创建了一个文本框,我想要这个切换按钮。当我尝试添加时,它会给我带来错误。如何在文本区域下方添加按钮?我还附上了代码片段 from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import QPropertyAnimation, QRectF, QSize, Qt, pyqtProper

我正在尝试在qt设计器中创建切换按钮。我也在网上查过,但我找不到怎么做。任何人都知道如何做切换开关按钮。我附上了一个样本按钮图像

编辑

我在下面创建了一个文本框,我想要这个切换按钮。当我尝试添加时,它会给我带来错误。如何在文本区域下方添加按钮?我还附上了代码片段

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QPropertyAnimation, QRectF, QSize, Qt, pyqtProperty
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import (
    QAbstractButton,
    QApplication,
    QHBoxLayout,
    QSizePolicy,
    QWidget,
)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
       MainWindow.setObjectName("MainWindow")
       MainWindow.resize(472, 180)
       self.centralwidget = QtWidgets.QWidget(MainWindow)
       self.centralwidget.setObjectName("centralwidget")
       self.url = QtWidgets.QLineEdit(self.centralwidget)
       self.url.setGeometry(QtCore.QRect(30, 20, 411, 31))
       font = QtGui.QFont()
       font.setFamily("MS Shell Dlg 2")
       font.setPointSize(10)
       font.setBold(True)
       font.setWeight(75)
       self.url.setFont(font)
       self.url.setAutoFillBackground(False)
       self.url.setStyleSheet("border-radius:10px;")
       self.url.setAlignment(QtCore.Qt.AlignCenter)
       self.url.setCursorMoveStyle(QtCore.Qt.LogicalMoveStyle)
       self.url.setObjectName("url")
       MainWindow.setCentralWidget(self.centralwidget)
       self.menubar = QtWidgets.QMenuBar(MainWindow)
       self.menubar.setGeometry(QtCore.QRect(0, 0, 472, 21))
       self.menubar.setObjectName("menubar")
       MainWindow.setMenuBar(self.menubar)
       self.statusbar = QtWidgets.QStatusBar(MainWindow)
       self.statusbar.setObjectName("statusbar")
       MainWindow.setStatusBar(self.statusbar)

       self.retranslateUi(MainWindow)
       QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
       _translate = QtCore.QCoreApplication.translate
       MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
       self.url.setPlaceholderText(_translate("MainWindow", "Playlist URL"))

if __name__ == "__main__":
    import sys
    main()
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Qt Designer设置窗口小部件的位置并初始化窗口小部件的某些属性,但创建带有自定义绘制开关的小部件并不起作用,因此必须使用python实现。很久以前,对于一个项目,实现一个这样的代码:

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_())
注意:Qt世界中另一个可能的解决方案是使用QML开关组件


注意:在中,我指出了如何将自定义小部件添加到.ui文件。

一个可能的解决方案是使用带有QCheckBox的样式表。只需使用以下代码编辑复选框的样式表:

    QCheckBox::indicator:unchecked {
        image: url(switch_off.png);
    }
    QCheckBox::indicator:checked {
        image: url(switch_on.png);
    }
最小运行示例:

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_())
不幸的是,如果您需要调整大小并希望复选框调整其外观,那么这并不总是很有效


唯一的替代方法是将QPushButton/QabStretchButton子类化(将
checkable()
属性设置为
True
),并自行实现
paintEvent
,正如所建议的。

感谢您抽出时间,我已编辑了我的问题,请帮助我联系this@Anonymous1)更正代码的缩进,2)在终端中运行,以便获得错误消息并在问题中显示,以及3)该代码与开关有什么关系?1)我更正了代码,2)问题是如何将上述代码片段添加到我的代码中,3)我正在尝试为应用程序创建gui,因此它需要Button。我想我清除了你的question@Anonymous如果您想在Qt Designer中插入小部件,那么这已经在前面的问题中得到了回答,正如我在更新的答案末尾指出的那样。为了便于您使用,因为我不想在我当前的答案中加入其他帖子中的相同内容,我在下面的链接中传递代码,我已经对您的链接进行了评论。请看