PyQt5 – 当鼠标悬停在未选中的单选按钮上时,将背景图片设置为单选按钮的指示灯

  • Post category:Python

首先,我们需要在Python环境下安装PyQt5库,可以通过pip命令进行安装:

pip install PyQt5

接着,我们需要在PyQt5中使用QButton组件,一种支持单选和多选的按钮。QButton中提供了一个hoverEnterEvent函数,可以在鼠标悬停时触发。我们可以在这个函数中设置QButton的背景图片,实现指示灯的效果。

下面是一个示例代码,演示了如何使用PyQt5实现当鼠标悬停在未选中的单选按钮时,将背景图片设置为指示灯的效果:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QRadioButton
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        # 创建一个单选按钮
        rbtn = QRadioButton('Single', self)
        rbtn.move(50, 50)

        # 设置选中和未选中的图片
        rbtn.setStyleSheet('QRadioButton::indicator:checked {image: url(checked.png);}'
                           'QRadioButton::indicator:unchecked {image: url(unchecked.png);}')

        # 设置未选中时的指示灯图片
        rbtn.hoverEnterEvent = lambda event: setattr(rbtn, 'styleSheet',
                                                     'QRadioButton::indicator:checked {image: url(checked.png);}'
                                                     'QRadioButton::indicator:unchecked {image: url(lamp.png);}')

        # 设置鼠标移出时恢复未选中时的图片
        rbtn.hoverLeaveEvent = lambda event: setattr(rbtn, 'styleSheet',
                                                     'QRadioButton::indicator:checked {image: url(checked.png);}'
                                                     'QRadioButton::indicator:unchecked {image: url(unchecked.png);}')

        self.setGeometry(300, 300, 300, 250)
        self.setWindowTitle('Hover Event')
        self.show()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

在这个例子中,我们创建了一个单选按钮,并为其设置了选中和未选中的背景图片。然后,我们覆写了QButton的hoverEnterEvent函数,在鼠标悬停时将未选中的图片替换为指示灯图片,并在鼠标移出时恢复原来的图片。

另外一个示例代码展示了如何使用QButtonGroup组织多个单选按钮,并在选中不同的按钮时设置不同的指示灯图片:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QRadioButton, QButtonGroup
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        # 创建单选按钮组
        bg = QButtonGroup(self)
        bg.buttonClicked[int].connect(self.buttonClicked)

        # 创建三个单选按钮,并添加到单选按钮组中
        rbtn1 = QRadioButton('Single-1', self)
        rbtn2 = QRadioButton('Single-2', self)
        rbtn3 = QRadioButton('Single-3', self)
        bg.addButton(rbtn1, 1)
        bg.addButton(rbtn2, 2)
        bg.addButton(rbtn3, 3)

        # 设置不同的选中和未选中的图片
        rbtn1.setStyleSheet('QRadioButton::indicator:checked {image: url(checked-1.png);}'
                           'QRadioButton::indicator:unchecked {image: url(unchecked-1.png);}')
        rbtn2.setStyleSheet('QRadioButton::indicator:checked {image: url(checked-2.png);}'
                             'QRadioButton::indicator:unchecked {image: url(unchecked-2.png);}')
        rbtn3.setStyleSheet('QRadioButton::indicator:checked {image: url(checked-3.png);}'
                             'QRadioButton::indicator:unchecked {image: url(unchecked-3.png);}')

        # 设置未选中时的指示灯图片
        rbtn1.hoverEnterEvent = lambda event: setattr(rbtn1, 'styleSheet',
                                                     'QRadioButton::indicator:checked {image: url(checked-1.png);}'
                                                     'QRadioButton::indicator:unchecked {image: url(lamp-1.png);}')
        rbtn2.hoverEnterEvent = lambda event: setattr(rbtn2, 'styleSheet',
                                                     'QRadioButton::indicator:checked {image: url(checked-2.png);}'
                                                     'QRadioButton::indicator:unchecked {image: url(lamp-2.png);}')
        rbtn3.hoverEnterEvent = lambda event: setattr(rbtn3, 'styleSheet',
                                                     'QRadioButton::indicator:checked {image: url(checked-3.png);}'
                                                     'QRadioButton::indicator:unchecked {image: url(lamp-3.png);}')

        # 设置鼠标移出时恢复未选中时的图片
        rbtn1.hoverLeaveEvent = lambda event: setattr(rbtn1, 'styleSheet',
                                                     'QRadioButton::indicator:checked {image: url(checked-1.png);}'
                                                     'QRadioButton::indicator:unchecked {image: url(unchecked-1.png);}')
        rbtn2.hoverLeaveEvent = lambda event: setattr(rbtn2, 'styleSheet',
                                                     'QRadioButton::indicator:checked {image: url(checked-2.png);}'
                                                     'QRadioButton::indicator:unchecked {image: url(unchecked-2.png);}')
        rbtn3.hoverLeaveEvent = lambda event: setattr(rbtn3, 'styleSheet',
                                                     'QRadioButton::indicator:checked {image: url(checked-3.png);}'
                                                     'QRadioButton::indicator:unchecked {image: url(unchecked-3.png);}')

        # 将单选按钮组在界面上布局
        rbtn1.move(50, 50)
        rbtn2.move(50, 80)
        rbtn3.move(50, 110)

        self.setGeometry(300, 300, 300, 250)
        self.setWindowTitle('Hover Event')
        self.show()

    def buttonClicked(self, id):
        # 选中单选按钮时,切换指示灯图片
        for btn in self.findChildren(QRadioButton):
            if btn.isChecked():
                btn.setStyleSheet(f'QRadioButton::indicator:checked {{image: url(checked-{btn.objectName()[-1]}.png);}}'
                                   f'QRadioButton::indicator:unchecked {{image: url(lamp-{btn.objectName()[-1]}.png);}}')
            else:
                btn.setStyleSheet(f'QRadioButton::indicator:checked {{image: url(checked-{btn.objectName()[-1]}.png);}}'
                                   f'QRadioButton::indicator:unchecked {{image: url(unchecked-{btn.objectName()[-1]}.png);}}')

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

这个例子中,我们创建了三个单选按钮,并将它们添加到一个单选按钮组中。当单选按钮被选中时,我们通过buttonClicked函数来切换不同的指示灯图片。在鼠标悬停和鼠标移动时,我们仍然使用hoverEnterEvent和hoverLeaveEvent函数来切换未选中的指示灯图片。