【问题标题】:PyQt5 - Hover signal for QPushButton created via Qt DesignerPyQt5 - 通过 Qt Designer 创建的 QPushButton 悬停信号
【发布时间】:2020-02-24 10:55:09
【问题描述】:

我刚刚创建了我的第一个用于存储个人数据的 PyQt 应用程序。 在 New Entry Dialog 上有一个按钮,单击该按钮时,会使用默认值填充 QLineEdits。 我想实现一个功能,以便当鼠标光标悬停在此默认按钮上时,您可以预览(可能通过 setPlaceholderText)QLineEdits 将设置的内容。

在寻找解决方案后,我发现了这个解决方案:How to Catch Hover and Mouse Leave Signal In PyQt5 继承 PushButton 并重新实现 enterEvent 和 leaveEvent。

但是,我已经使用 Qt Designer 创建了我的 GUI,并且对于如何应用此解决方案有点困惑,因为 QPushButton 是在 Designer 的 .ui 文件中创建的,我无法真正进行更改...

这是使用 pyuic5 转换为 .py 时 .ui 文件的摘录

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")

        self.pushButton_contact_defaut = QtWidgets.QPushButton(self.groupBox_client)
        self.pushButton_contact_defaut.setGeometry(QtCore.QRect(80, 130, 165, 22))
        self.pushButton_contact_defaut.setMouseTracking(True)
        self.pushButton_contact_defaut.setAutoDefault(False)
        self.pushButton_contact_defaut.setObjectName("pushButton_contact_defaut")

正如我所说,我无法在此处进行更改,因为每次更改 ui 文件时都会重置代码...

这也是我的主要 python 文件的摘录,我在其中“处理”所有连接和逻辑。 我显然不太熟悉 Python 和 PyQt(或任何与编程相关的东西!) 有没有办法从我的代码中“重新定义”按钮,这是解决问题的最佳方法,还是我还缺少其他东西?

class NewEntry(NE_Base, NE_Ui):
    def __init__(self):
        super().__init__()
        QDialog.__init__(self, parent=main_window)
        self.ui = NE_Ui()
        self.ui.setupUi(self)
        self.setWindowModality(0)
        self.ui.pushButton_contact_defaut.clicked.connect(self.contact_defaut)

感谢您的帮助!

编辑:根据 musicamante 的回答,我让它在我的应用程序中正常工作,我有 2 个按钮,通过执行以下操作“填充”不同的 lineEdit。

我在 pushButton 上应用了 .installEventFilter(self) 并添加了:

 def eventFilter(self, source, event):
    if event.type() == QtCore.QEvent.Enter and source == self.ui.pushButton_contact_defaut:
        self.ui.contact_text.setPlaceholderText(self.contact_base)
        self.ui.cell_text.setPlaceholderText(self.cell)
        self.ui.email_text.setPlaceholderText(self.courriel)

    if event.type() == QtCore.QEvent.Enter and source == self.ui.pushButton_copy_adress:
        self.ui.street_text.setPlaceholderText(self.street)
        self.ui.city_text.setPlaceholderText(self.city)
        self.ui.postal_text.setPlaceholderText(self.postal)

    elif event.type() == QtCore.QEvent.Leave:
        self.ui.contact_text.setPlaceholderText('')
        self.ui.cell_text.setPlaceholderText('')
        self.ui.email_text.setPlaceholderText('')
        self.ui.street_text.setPlaceholderText('')
        self.ui.city_text.setPlaceholderText('')
        self.ui.postal_text.setPlaceholderText('')

    return super().eventFilter(source, event)

以这种方式处理多个 pushButton 似乎有点尴尬,希望有人也能在这个问题上启发我,但与此同时,它可以工作!

【问题讨论】:

  • 除了子类化每个按钮并在 Designer 中使用提升的小部件(在 SO 中搜索相关问题)外,使用单个 eventFilter 是最直接和最常用的方法,因此您的实现方式没有任何问题;您最终可以稍微通过将if event.type() == QtCore.QEvent.Enter 组合在一个 if 语句中来改进逻辑,然后检查按钮实例。

标签: python pyqt


【解决方案1】:

您可以在要跟踪的按钮上安装事件过滤器。事件过滤器是一个系统,它“监视”被监视对象接收到的事件,并最终可以在之后做一些事情(包括忽略事件本身)。

在您的情况下,您需要检查 EnterLeave 事件,每次鼠标进入或离开小部件时都会触发这些事件(它们通常被实现在enterEventleaveEvents 子类中)。

class NewEntry(QDialog, NE_Ui):
    def __init__(self, parent=None):
        super().__init__(parent)
        # Don't do the following, is unnecessary: you already called __init__
        # QDialog.__init__(self, parent=main_window)

        self.ui = NE_Ui()
        self.ui.setupUi(self)
        self.ui.pushButton_contact_defaut.installEventFilter(self)

    def eventFilter(self, source, event):
        if event.type() == QEvent.Enter:
            self.ui.lineEdit.setPlaceholderText('Default text')
        elif event.type() == QEvent.Leave:
            self.ui.lineEdit.setPlaceholderText('')
        # *always* return a bool value (meaning that the event has been acted upon
        # or not), it's common to call the base class implementation and then
        # return the result of that
        return super().eventFilter(source, event)

永远不要编辑pyuic 生成的文件,也不要开始使用它们作为代码的开始。正如您已经发现的那样,每次更改 ui 时它们都会被清除,最好将它们作为模块导入(或通过uic.loadUi('somefile.ui', self) 使用它们)。

【讨论】:

  • 非常感谢您的帮助musicamante!这正是我所需要的,我肯定会尝试阅读更多关于 eventFilter 的内容,以便我能更好地理解最后一个 return 语句......鉴于我有多个按钮需要根据同一事件执行不同的操作(请参阅我编辑的问题),但它有效 =)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-22
  • 2017-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-04
  • 2020-10-11
相关资源
最近更新 更多