QTimer::singleShot() 在给定对象的父类中查找指定的插槽,而不是对象本身

QTimer::singleShot() looks for the specified slot in the given object's parent class, not the object itself

本文关键字:对象 插槽 父类 singleShot QTimer 查找      更新时间:2023-10-16

我对Qt相当陌生,我对现有的Qt应用程序做了一些简单的修改,但我还没有从头开始创建任何应用程序。
我对c++的某些方面(类继承等)也没有太多的经验。

我创建了一个新的Code::Blocks Qt4-based项目,并修改了模板一点。我添加了两个文件。
目前该项目包含三个文件:main.cpp、app.h和app.cpp。
这是main.cpp:

的内容。
#include <QTimer>
#include "app.h"
int main(int argc, char* argv[]) {
    TestApp app(argc, argv);
    QTimer::singleShot(1000, &app, SLOT(timeout()));
    return app.exec();
}
app.h的样子如下:
#ifndef APP_H_INCLUDED
#define APP_H_INCLUDED
#include <QApplication>
class TestApp: public QApplication {
    public:
    TestApp(int &argc, char **argv);
    public slots:
    void timeout();
};
#endif

这是app.cpp:

#include "app.h"
#include <QDebug>
TestApp::TestApp(int &argc, char **argv): QApplication(argc, argv) {
}
void TestApp::timeout() {
    qDebug() << "timeout called";
}

我希望程序输出&;timeout called&;启动后一秒。不幸的是,这不起作用。当调用QTimer::singleShot()时,控制台显示:

Object::connect: No such slot QApplication::timeout() in [path to the main.cpp file]
Object::connect:  (receiver name: 'QtTests')

我不知道该怎么处理。

您只是在TestApp类中缺少Q_OBJECT宏:

class TestApp: public QApplication {
    Q_OBJECT
    public:
    ...

这是整个信号/槽基础设施工作所必需的(从具有此宏的类派生是不够的)。

(确保你做了一个完整的,干净的构建后,更改-如果你不使用qmake或其他一些qt感知的构建系统,你需要自己运行moc。)

参考QObject文档:

注意Q_OBJECT宏对于任何实现信号、槽或属性的对象都是强制性的。您还需要在源文件上运行Meta Object Compiler。我们强烈建议在QObject的所有子类中使用这个宏,不管它们是否实际使用信号、槽和属性,因为不这样做可能会导致某些函数表现出奇怪的行为。

您需要创建一个moc文件,如果您将Q_OBJECT宏放在类中,则使用qmake创建该文件。

因此,要修复您的示例,您需要将类更改为:

class TestApp: public QApplication {
    Q_OBJECT
    public:
    TestApp(int &argc, char **argv);
    public slots:
    void timeout();
};