临时更改标签样式(模仿按钮)

时间:2018-10-03 18:05:55

标签: python qlabel pyside2

由于我的想法不多了,我需要问大家一些建议。我正在使用onclickable标签。我已经完成了一些“可单击标签”类并处理了mouseover事件-更改了标签边框,并在鼠标离开时返回到正常状态。

现在,我希望它在标签上具有自定义发光效果,但我希望它在单击后0.5秒后恢复正常状态。

我希望带有图像的标签模仿按钮。 time.sleep不能很好地工作,特别是对于垃圾邮件点击,它会冻结应用程序主线程。

希望我不是在重新发明轮子,但据我所知这是要走的路。

这里有示例代码,感谢您的回答。

from PySide2.QtWidgets import QLabel, QSizePolicy, QGraphicsDropShadowEffect
from PySide2.QtGui import QPixmap
from PySide2.QtCore import (Signal, QEvent, QObject, QRect)


class ClickableLabel(QLabel):
    def __init__(self, pic_path, width, height, border_color, click_function):
        super(ClickableLabel, self).__init__()

        # Setting the picture path and setting pixmap to label
        self.pic_path = pic_path
        self.pixmap = QPixmap(self.pic_path)
        self.setPixmap(self.pixmap)

        # Set the size
        self.setFixedSize(width, height)

        # Enable tracking and assign function
        self.setMouseTracking(True)
        self.click_function = click_function

        # Set default 
        if border_color is None:
            self.border_color = 'lightblue'
        else:
            self.border_color = border_color

    def mouseMoveEvent(self, event):
        # event.pos().x(), event.pos().y()
        self.setStyleSheet("border: 1px solid " + str(self.border_color) + ";")

    def leaveEvent(self, event):
        # event.pos().x(), event.pos().y()
        self.setStyleSheet("border: None")

    def mousePressEvent(self, event):
        self.click_function()

        effect = QGraphicsDropShadowEffect(self)
        effect.setOffset(0, 0)
        effect.setBlurRadius(20)
        effect.setColor(self.border_color)
        self.setGraphicsEffect(effect)

1 个答案:

答案 0 :(得分:0)

如果要在一段时间后运行任务,则不应该使用time.sleep(),因为它会阻塞GUI导致其无法正常运行,因此最好的选择是使用QTimer::singleShot()

另一方面,我看到您正在传递一个函数,以便它在单击时执行不可扩展的任务,在Qt中,正确的做法是创建信号,并且好处是您可以连接相同的信号不需耦合即可用于多个功能,也就是说,发出信号的功能必须事先不知道谁将接收信号。

我建议为参数的缺陷取值,我花时间改进了您的代码:

from PySide2 import QtCore, QtGui, QtWidgets


class ClickableLabel(QtWidgets.QLabel):
    clicked = QtCore.Signal()

    def __init__(self, pic_path="", width=80, height=30, border_color=QtGui.QColor("lightblue"), parent=None):
        super(ClickableLabel, self).__init__(parent)
        self.setPixmap(QtGui.QPixmap(pic_path))
        self.setFixedSize(width, height)
        self.setMouseTracking(True)
        self.border_color = QtGui.QColor(border_color)
        self.effect = QtWidgets.QGraphicsDropShadowEffect(self,
            offset=QtCore.QPointF(0, 0),
            blurRadius=20,
            color=self.border_color)
        self.setGraphicsEffect(self.effect)
        self.disable_effect()

    def mouseMoveEvent(self, event):
        self.setStyleSheet("border: 1px solid {};".format(self.border_color.name()))
        super(ClickableLabel, self).mouseMoveEvent(event)

    def leaveEvent(self, event):
        self.setStyleSheet("border: None")
        super(ClickableLabel, self).leaveEvent(event)

    def mousePressEvent(self, event):
        self.clicked.emit()
        self.effect.setEnabled(True)
        QtCore.QTimer.singleShot(500, self.disable_effect)
        super(ClickableLabel, self).mousePressEvent(event)

    @QtCore.Slot()
    def disable_effect(self):
        self.effect.setEnabled(False)


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)

    def on_click():
        print("click")

    w = ClickableLabel(pic_path="heart.png")
    w.clicked.connect(on_click)
    w.show()
    sys.exit(app.exec_())