覆盖子类中的 Qt 插槽

Posted

技术标签:

【中文标题】覆盖子类中的 Qt 插槽【英文标题】:Override Qt slot in subclass 【发布时间】:2015-03-20 15:54:50 【问题描述】:

我有一个基类,它定义了一个 Qt 插槽

class Base

public:
    Base()
    
        connect(otherobject, SIGNAL(mySignal), this, SLOT(mySlot));
    
public slots:
    virtual void mySlot()
    

子类 A 只是实现了一些其他的东西。子类 B 覆盖插槽

class SubB : Base

public:
    SubB() : Base() 
    
        // Necessary?
        connect(otherobject, SIGNAL(mySignal), this, SLOT(mySlot));
    
public slots:
    virtual void mySlot() override
    

插槽的覆盖是否也替换了之前在 Bass 构造函数中完成的连接(即 SubB 中的连接是不必要的)?

【问题讨论】:

要 100% 正确,不要忘记 Base 应该继承自 QObject 并且您必须将 Q_OBJECT 宏放在两个类中;) 【参考方案1】:

它变得更好:您不需要对派生类中的插槽进行任何特殊处理。无需将其设为虚拟(它已经符合 C++ 语义),也无需再次将其设为插槽(它已经符合 Qt 语义)。在Derived 中添加第二个连接是不正确的,它只会导致每次激活信号时都会激活插槽两次。

请记住,信号和槽是常规的 C++ 方法,并且槽是从机器生成的代码中调用的,看起来就像您在没有指定它应该位于的特定类的情况下调用槽一样。因此,虚拟槽的作用就像您想象的那样鉴于 C++ 的语义,它应该。

以下就足够了:

class Base : public QObject

  Q_OBJECT
public:
  Base(QObject * src, QObject * parent = 0) : QObject(parent)
   connect(src, SIGNAL(mySignal), SLOT(mySlot)); 
  Q_SLOT virtual void mySlot() 
;

class Derived : public Base

  Q_OBJECT
public:
  Derived(QObject * src, QObject * parent = 0) : Base(src, parent) 
  void mySlot() Q_DECL_OVERRIDE  ... 
;

【讨论】:

【参考方案2】:

您不需要在子类构造函数中放入相同的connect。当SubB 对象被创建时,Base 构造函数中的connect 将连接正确的插槽(SubB 中被覆盖的那个)。

【讨论】:

这就是我所希望的。在文档中找不到任何内容。 @Simon 查看 moc 为实现Base 生成的代码真的很有帮助。您可以轻松查看插槽是如何调用的。

以上是关于覆盖子类中的 Qt 插槽的主要内容,如果未能解决你的问题,请参考以下文章

Qt - 由 qt 对象发送的信号调用由接收器对象覆盖的事件函数

Qt Designer PyQt5 覆盖 CloseEvent 子窗口不起作用

子类化并覆盖 PySide2 小部件方法;我在哪里可以找到参考资料?

覆盖 mousePressEvent 后 Qt Widget 调整大小

使用 QT 设计器创建的新插槽的代码在哪里?

QT5 插槽未在子类中调用