如何声明从QApplication派生的Qt类并覆盖notify函数?

时间:2018-06-15 20:13:04

标签: c++ qt qt5

我试图覆盖从QApplication派生的类中的notify函数:

#include "mainwindow.h"
#include <QApplication>
#include <typeinfo>

class Application final : public QApplication
{
    Q_OBJECT
public:
    Application(int& argc, char** argv) : QApplication(argc, argv) { }
    virtual bool notify(QObject *receiver, QEvent *e) override;
};

bool Application::notify(QObject* receiver, QEvent* event)
{
    try
    {
        return QApplication::notify(receiver, event);
    }
    catch (std::exception &e)
    {
        qFatal("Error %s sending event %s to object %s (%s)",
            e.what(), typeid(*event).name(), qPrintable(receiver->objectName()),
            typeid(*receiver).name());
    }
    catch (...)
    {
        qFatal("Error <unknown> sending event %s to object %s (%s)",
            typeid(*event).name(), qPrintable(receiver->objectName()),
            typeid(*receiver).name());
    }
    return false;
}

int main(int argc, char *argv[])
{
    Application a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

但是我在类声明中遇到了编译错误:

error: undefined reference to `vtable for Application'

申报此课程的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

根据docs

  

<强> Q_OBJECT

     

Q_OBJECT宏必须出现在类的私有部分中   声明自己的信号和插槽或使用其他信号的定义   Qt的元对象系统提供的服务。

在您的情况下,您没有创建任何信号或插​​槽,因此没有必要删除它。

#include "mainwindow.h"
#include <QApplication>

class Application final: public QApplication{
public:
    using QApplication::QApplication;
    bool notify(QObject *receiver, QEvent *e) override;
};

bool Application::notify(QObject* receiver, QEvent* event)
{
    try
    {
        return QApplication::notify(receiver, event);
    }
    catch (std::exception &e)
    {
        qFatal("Error %s sending event %s to object %s (%s)",
            e.what(), typeid(*event).name(), qPrintable(receiver->objectName()),
            typeid(*receiver).name());
    }
    catch (...)
    {
        qFatal("Error <unknown> sending event %s to object %s (%s)",
            typeid(*event).name(), qPrintable(receiver->objectName()),
            typeid(*receiver).name());
    }
    return false;
}

int main(int argc, char *argv[])
{
    Application a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

如果在应用程序中你要创建信号或插槽,那么Q_OBJECT是强制性的,这个宏将生成一个main.moc文件,你必须包含在 main.cpp 中。 / p>

#include "mainwindow.h"
#include <QApplication>

class Application final: public QApplication{
    Q_OBJECT
public:
    using QApplication::QApplication;
    bool notify(QObject *receiver, QEvent *e) override;
};

bool Application::notify(QObject* receiver, QEvent* event)
{
    [...]
}

int main(int argc, char *argv[])
{
    Application a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

#include "main.moc" // <---

然后执行构建菜单中的运行qmake ,然后进行编译。

注意:

如果将应用程序移动到.h文件,则不必包含moc,因为qmake将在您创建的Makefile中执行此操作。