代码之家  ›  专栏  ›  技术社区  ›  gornvix

如何声明从qapplication派生的qt类并重写notify函数?

  •  1
  • gornvix  · 技术社区  · 6 年前

    我试图重写从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 回复  |  直到 6 年前
        1
  •  1
  •   eyllanesc Yonghwan Shin    6 年前

    根据 docs :

    Q-对象

    q_object宏必须出现在类的private部分 声明自己的信号和插槽或使用其他 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_对象如果是必需的,则此宏将生成 main.moc 必须包含在 主CPP .

    #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" // <---
    

    然后执行 运行QQuE 那是在 建造 菜单,然后编译。

    注:

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