PyQt5 – 鼠标悬停时为不确定的复选框设置皮肤

  • Post category:Python

下面是针对Python中PyQt5库的“鼠标悬停时为不确定的复选框设置皮肤”使用攻略:

1. 安装 PyQt5 库

首先,在开始使用 PyQt5 库之前,我们需要先安装它。可以使用 pip 命令进行安装:

pip install PyQt5

2. 创建界面窗口

我们可以使用 Qt Designer 工具创建窗口界面,也可以直接使用 PyQt5 代码来创建窗口和控件。在这里,我们以代码方式创建窗口界面:

from PyQt5.QtWidgets import QApplication, QWidget, QCheckBox
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt

class App(QWidget):

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

        self.title = 'PyQt5 Checkbox Example'
        self.left = 200
        self.top = 200
        self.width = 300
        self.height = 200

        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.checkbox = QCheckBox('Checkbox', self)
        self.checkbox.move(20, 20)
        self.checkbox.stateChanged.connect(self.changeTitle)

        self.show()

    def changeTitle(self, state):
        if state == Qt.Checked:
            self.setWindowTitle('Checkbox Checked')
        else:
            self.setWindowTitle('Checkbox Unchecked')

if __name__ == '__main__':
    app = QApplication([])
    ex = App()
    app.exec_()

在这个例子中,我们创建了一个继承自 QWidget 的类 App,并设置了窗口标题、大小、位置和控件 —— 一个复选框,并连接复选框的状态改变信号与槽函数 changeTitle。使用 stateChanged 信号可以获取复选框的状态,并根据状态改变窗口标题。

3. 为复选框设置悬停皮肤

为了在鼠标悬停时为不确定的复选框设置皮肤,我们可以使用复选框的 enterEvent 和 leaveEvent 事件。

在鼠标悬停复选框时,我们将复选框的状态设置为半选中状态,并向复选框添加样式表。在鼠标移出复选框时,我们将复选框的状态设置为之前的状态(选中或未选中状态)。

下面是为复选框添加悬停事件的完整代码:

from PyQt5.QtWidgets import QApplication, QWidget, QCheckBox
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt

class App(QWidget):

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

        self.title = 'PyQt5 Checkbox Example'
        self.left = 200
        self.top = 200
        self.width = 300
        self.height = 200

        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.checkbox = QCheckBox('Checkbox', self)
        self.checkbox.move(20, 20)
        self.checkbox.stateChanged.connect(self.changeTitle)
        self.checkbox.setMouseTracking(True)
        self.checkbox.enterEvent = self.enterCheckbox
        self.checkbox.leaveEvent = self.leaveCheckbox

        self.show()

    def changeTitle(self, state):
        if state == Qt.Checked:
            self.setWindowTitle('Checkbox Checked')
        else:
            self.setWindowTitle('Checkbox Unchecked')

    def enterCheckbox(self, event):
        if self.checkbox.checkState() == Qt.Unchecked:
            self.checkbox.setCheckState(Qt.PartiallyChecked)
        self.checkbox.setStyleSheet('QCheckBox::indicator:hover{ border: 2px solid red; }')

    def leaveCheckbox(self, event):
        self.checkbox.setStyleSheet('')
        self.checkbox.setCheckState(self.checkbox.checkState())

if __name__ == '__main__':
    app = QApplication([])
    ex = App()
    app.exec_()

上述代码中,我们将复选框对象的 setMouseTracking 方法设为 True,表示开启鼠标跟踪功能,这样可以在鼠标进入时触发 enterEvent 事件。同理,离开操作也会自动触发 leaveEvent 事件。

enterCheckbox 函数为进入事件的处理函数,该函数中,如果复选框的状态为未选中,则将该复选框设置为半选中状态,并添加悬停时的样式表。reduceOpacity 函数为离开事件的处理函数,该函数将移除悬停时的样式表并恢复之前的状态。

4. 示例

下面我们通过两个例子来说明这个“鼠标悬停时为不确定的复选框设置皮肤”攻略的使用方法。

示例一

我们现在有一个界面,里面有多个复选框,需要在鼠标悬停时为复选框设置皮肤。

from PyQt5.QtWidgets import QApplication, QWidget, QCheckBox, QVBoxLayout
from PyQt5.QtCore import Qt

class App(QWidget):

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

        self.title = 'PyQt5 Checkbox Example'
        self.left = 200
        self.top = 200
        self.width = 300
        self.height = 200

        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        layout = QVBoxLayout()

        self.checkbox1 = QCheckBox('Checkbox 1')
        layout.addWidget(self.checkbox1)

        self.checkbox2 = QCheckBox('Checkbox 2')
        layout.addWidget(self.checkbox2)

        self.checkbox3 = QCheckBox('Checkbox 3')
        layout.addWidget(self.checkbox3)

        self.checkbox1.setMouseTracking(True)
        self.checkbox1.enterEvent = lambda event: self.enterCheckbox(event, self.checkbox1)
        self.checkbox1.leaveEvent = lambda event: self.leaveCheckbox(event, self.checkbox1)

        self.checkbox2.setMouseTracking(True)
        self.checkbox2.enterEvent = lambda event: self.enterCheckbox(event, self.checkbox2)
        self.checkbox2.leaveEvent = lambda event: self.leaveCheckbox(event, self.checkbox2)

        self.checkbox3.setMouseTracking(True)
        self.checkbox3.enterEvent = lambda event: self.enterCheckbox(event, self.checkbox3)
        self.checkbox3.leaveEvent = lambda event: self.leaveCheckbox(event, self.checkbox3)

        self.setLayout(layout)
        self.show()

    def enterCheckbox(self, event, checkbox):
        if checkbox.checkState() == Qt.Unchecked:
            checkbox.setCheckState(Qt.PartiallyChecked)
        checkbox.setStyleSheet('QCheckBox::indicator:hover{ border: 2px solid red; }')

    def leaveCheckbox(self, event, checkbox):
        checkbox.setStyleSheet('')
        checkbox.setCheckState(checkbox.checkState())

if __name__ == '__main__':
    app = QApplication([])
    ex = App()
    app.exec_()

示例二

我们现在有一个界面,里面有多个复选框,需要在鼠标悬停时为复选框设置皮肤。除了悬停时,我们还需要在复选框被选中时对复选框的样式进行修改。

from PyQt5.QtWidgets import QApplication, QWidget, QCheckBox, QVBoxLayout
from PyQt5.QtCore import Qt

class App(QWidget):

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

        self.title = 'PyQt5 Checkbox Example'
        self.left = 200
        self.top = 200
        self.width = 300
        self.height = 200

        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        layout = QVBoxLayout()

        self.checkbox1 = QCheckBox('Checkbox 1')
        layout.addWidget(self.checkbox1)

        self.checkbox2 = QCheckBox('Checkbox 2')
        layout.addWidget(self.checkbox2)

        self.checkbox3 = QCheckBox('Checkbox 3')
        layout.addWidget(self.checkbox3)

        self.checkbox1.setMouseTracking(True)
        self.checkbox1.stateChanged.connect(lambda state: self.changeState(state, self.checkbox1))
        self.checkbox1.enterEvent = lambda event: self.enterCheckbox(event, self.checkbox1)
        self.checkbox1.leaveEvent = lambda event: self.leaveCheckbox(event, self.checkbox1)

        self.checkbox2.setMouseTracking(True)
        self.checkbox2.stateChanged.connect(lambda state: self.changeState(state, self.checkbox2))
        self.checkbox2.enterEvent = lambda event: self.enterCheckbox(event, self.checkbox2)
        self.checkbox2.leaveEvent = lambda event: self.leaveCheckbox(event, self.checkbox2)

        self.checkbox3.setMouseTracking(True)
        self.checkbox3.stateChanged.connect(lambda state: self.changeState(state, self.checkbox3))
        self.checkbox3.enterEvent = lambda event: self.enterCheckbox(event, self.checkbox3)
        self.checkbox3.leaveEvent = lambda event: self.leaveCheckbox(event, self.checkbox3)

        self.setLayout(layout)
        self.show()

    def enterCheckbox(self, event, checkbox):
        if checkbox.checkState() == Qt.Unchecked:
            checkbox.setCheckState(Qt.PartiallyChecked)
        checkbox.setStyleSheet('QCheckBox::indicator:hover{ border: 2px solid red; }')

    def leaveCheckbox(self, event, checkbox):
        checkbox.setStyleSheet('')
        checkbox.setCheckState(checkbox.checkState())

    def changeState(self, state, checkbox):
        if state == Qt.Checked:
            checkbox.setStyleSheet('QCheckBox::indicator:checked{ background-color: green; }')
        else:
            checkbox.setStyleSheet('')

if __name__ == '__main__':
    app = QApplication([])
    ex = App()
    app.exec_()

在上述代码中,我们为每个复选框连接 stateChanged 信号与 changeState 槽函数,用于检查复选框的状态并设置皮肤。在复选框状态更改时,如果状态为选中,则添加一个绿色背景,否则恢复正常颜色。