QPushButton FocusIn 生成哪个信号?

4 投票
2 回答
2152 浏览
提问于 2025-04-15 18:51

我正在创建一个小的PyQt应用程序,但在实现鼠标悬停效果时遇到了困难。

我有一个QMainWindow,里面有三个按钮,分别叫做createProfileButtondownloadPackagesButtoninstallPackagesButton。这些按钮都是QPushButton类型的。

现在,我创建了一个标签,用来显示当鼠标悬停在这些按钮上时的文本。我查阅了文档,发现可以通过重写一些方法来处理这个问题。

  • focusInEvent(self, QFocusEvent)
  • focusOutEvent(self, QFocusEvent)

这意味着我需要为每个按钮扩展QPushButton,并且每个按钮都要有一个对应的类的对象。我试着寻找当鼠标悬停或离开按钮时发出的信号,但没有找到。网上得到的帮助都是让我实现这两个方法。

难道扩展一个类并为每个按钮创建一个对象不是太复杂了吗?如果有一个信号就好了,可惜我找不到任何信号。

所以我检查了整个继承层次结构,发现没有FocusInFocusOut的信号。

2 个回答

1

在一个父控件中,还有另一种接收焦点信号的方法。你可以添加一个事件过滤器:

class MyParent(QWidget):
    def __init__(self):
        #...
        self.mybutton.installEventFilter()

    def eventFilter(self, obj, event):
        if obj is self.mybutton and event.type() == QEvent.FocusOut:
           #...
        return QWidget.eventFilter(self, obj, event)
4

正如你所说,这个功能没有现成的信号。你有两个基本的选择。

选择一 - 子类化:

class FocusEmittingButton(QPushButton):
    #...
    def focusInEvent(self, event):
        # emit your signal

你可以在你的客户端代码中连接到这个信号。如果需要的话,你还可以使用设计器的 Promote To 功能,把每个按钮提升为 FocusEmittingButton 类型。你只需要子类化一次,然后确保不同的按钮都是同一种类型。

选择二 - 使用 QApplication.focusChanged

你也可以利用 QApplication.focusChanged(oldQWidget, newQWidget)。这样的话,你就不需要子类化和重写焦点事件了。相反,你只需连接到 QApplication.focusChanged 信号,然后在处理函数中做出响应。

撰写回答