qt 自定义信号 QMetaObject::connectSlotsByName是否不能使用?

qt 在自定义类中自定义信号,类函数调用emit 通过QMetaObject::connectSlotsByName不起作用,使用connect可以正常接收信号,是不是只能通过手动connect

按理说,应该是可以的,你是不是命名不规范,信号函数的命名应以signal_开头,槽函数的命名应以on_开头,后面跟着相同的名字

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这篇文章讲的很详细,请看:【Qt】关于QMetaObject::connectSlotsByName()
  • 你还可以看下qt参考手册中的 qt connectSlotsByName: QMetaObject
  • 以下回答来自chatgpt:

    问题标题: Qt中自定义信号使用QMetaObject::connectSlotsByName无效的原因是什么?

    问题答案: 在Qt中,可以使用connectSlotsByName来自动连接信号和槽函数。这种自动连接机制基于QObject的元对象系统(Meta-Object System)来实现。

    然而,connectSlotsByName只能自动连接到通过Qt设计器创建的对象或类中的槽函数。这是因为connectSlotsByName通过检查对象的元对象的名称和槽函数的名称来进行连接。当使用Qt设计器创建的对象或类时,它们会自动在元对象系统中注册,并按照特定的命名规则进行命名。这使得connectSlotsByName可以准确地找到并连接这些槽函数。

    但是,当我们自定义的类中定义了信号时,并不会自动在元对象系统中注册,也不会按照Qt设计器中的命名规则进行命名。因此,connectSlotsByName无法准确地找到和连接这些信号。

    如果我们想使用connectSlotsByName来连接自定义的信号,我们可以通过在自定义类的构造函数中手动调用QMetaObject::connectSlotsByName来实现。具体步骤如下:

    1. 在自定义类的头文件中声明信号和槽函数:
    class MyClass : public QObject
    {
        Q_OBJECT
    public:
        MyClass(QObject *parent = nullptr);
    
    signals:
        void mySignal();
    
    private slots:
        void mySlot();
    };
    
    1. 在自定义类的源文件中实现构造函数,用QMetaObject::connectSlotsByName(this)来手动连接信号和槽函数:
    MyClass::MyClass(QObject *parent) : QObject(parent)
    {
        QMetaObject::connectSlotsByName(this);
    }
    

    这样,当创建一个MyClass的对象时,就会自动连接到名为mySignal的信号和名为mySlot的槽函数。

    需要注意的是,尽管可以通过以上方法手动连接自定义的信号和槽函数,但是由于元对象系统的限制,connectSlotsByName仅适用于使用了特定命名规则的对象或类中的槽函数。如果我们的自定义信号和槽函数的命名规则不符合这些规则,仍然需要使用connect来手动连接信号和槽函数。

    因此,回答你的问题,是的,只能通过手动使用connect来进行信号连接,除非我们在自定义类的构造函数中手动调用QMetaObject::connectSlotsByName来实现自动连接。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^