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

8
我对Qt还比较新手。我对现有的Qt应用程序进行了一些简单的修改,但是还没有从头开始创建过。
我对C++的某些方面(如类继承等)也没有太多经验。
我创建了一个基于Code::Blocks Qt4的新项目,并对模板进行了一些修改。我添加了两个文件。
目前该项目包含三个文件: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')

我不知道该如何处理这个。
2个回答

6
您的TestApp类中简单地缺少Q_OBJECT宏:
class TestApp: public QApplication {
    Q_OBJECT

    public:
    ...

这是整个信号/槽架构工作所必需的(从具有此宏的类派生不足以满足要求)。(确保在更改后进行完整的清理构建 - 如果您不使用qmake或其他Qt感知的构建系统,则需要自行运行moc。)
请参阅QObject文档以供参考:
请注意,对于实现信号、槽或属性的任何对象,Q_OBJECT宏都是强制性的。您还需要在源文件上运行元对象编译器。我们强烈建议在所有QObject子类中使用此宏,无论它们是否实际使用信号、槽和属性,因为不这样做可能会导致某些函数表现出奇怪的行为。

3

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

因此,为了修复您的示例,您需要将您的类更改为以下内容:

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

提到 moc 文件 加 1 分!当使用 CMake 构建时,将 Q_OBJECT 放入类声明中是不够的。 - Melebius
1
@Melebius,为此,您需要使用QT4_WRAP_CPP,这样cmake就会解析头文件并生成moc文件。 - BЈовић

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接