• QT踩坑记录1-Q_OBJECT编译问题


    QT踩坑记录1-Q_OBJECT编译问题

    错误输出

    Q_OBJECT 宏错误的地方会编译出现这样的错误, 无法找到....

    由于自己不想再看到这个错误, 此处 复制自 参考连接1, 主要是连接错误 LNK2001 ,

    1>LoginDlg.obj : error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const * __thiscall CLoginDlg::metaObject(void)const " (?         metaObject@CLoginDlg@@UBEPBUQMetaObject@@XZ)
    1>LoginDlg.obj : error LNK2001: 无法解析的外部符号 "public: virtual void * __thiscall CLoginDlg::qt_metacast(char const *)" (?qt_metacast@CLoginDlg@@UAEPAXPBD@Z)
    1>LoginDlg.obj : error LNK2001: 无法解析的外部符号 "public: virtual int __thiscall CLoginDlg::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@CLoginDlg@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
    1>D:VC++QtTMyDialog\MyDialog.exe : fatal error LNK1120: 3 个无法解析的外部命令
    

    介绍

    首先看一下一个基本的 QT 类的简单实现, 继承自 QObject, 然后定义了 一个信号 signals_dosomething 和 一个槽函数 slots_dosomething ,
    信号函数不用去实现, 只需要 设定与相应的函数进行连接即可, 即 使用 QObject::connect 连接, 且信号函数与槽函数的参数一致, 信号这里的连接与函数参数也是一个坑, 后续会更新相应的章节, 那类中 最开始 的地方 为什么要有一个 宏 Q_OBJECT 这里可以参考 QT Q_OBJECT, 里面做了详细的解释

    #include <QObject>
    class MyClass:public QObject
    {
        Q_OBJECT
    signals:
        void signals_dosomething(int n);
    
    public slots:
        void slots_dosomething(int n)
        {
            m_value_ = n;
        }
    private:
        int m_value_;
    public:
        MyClass(QObjet *parent = nullptr)
            :QObject(parent),
             m_value_(0)
        {
            QObject::connect(this,
                            &MyClass::signals_dosomething,
                            this,
                            &MyClass::slots_dosomething,
                            Qt::DirectConnection);
            
        }    
    }

    解决

    由于本人使用的是QT构建工程,然后使用 VS 的 QT VS Tools 将QT 工程转生成的 VS 工程,
    存在各种问题,甚至出现 QT编译通过 VS 编译不通过的问题, 这里使用最暴力的方式, 直接使用 QT 的 moc 命令 将相应 类的声明 h 文件 moc 成cpp 文件,

    moc MyClass.h -o moc_MyClass.cpp

    然后将cpp 文件放置到相应的生成目录下面即可, 一般在 解决方案/工程/debug 下面,里面全是 moc_* 的cpp 文件和 obj 文件
    注意查找自己的目录下面即可, 在手动 moc 生成之后, 之前编译不通过的 VS工程也编译通过了,
    这里猜想是,

    利用Qt编程时,写好.h、.cpp文件并第一次编译之后,若.h文件中定义类时没有添加Q_OBJECT宏以及信号函数、槽函数,VS编译命令中就没有moc命令,就不会调用Qt的moc工具以生成moc_*.cpp文件;并且即使添加了Q_OBJECT宏之后,VS也不会自动添加moc命令,因而不会生成moc文件。
    VS在LINK时,找不到moc文件,就出现了error LNK2001的错误。

    更多

    参考链接

    1. error LNK2001: 无法解析的外部符号
    2. What does the Q_OBJECT macro do? Why do all Qt objects need this macro?
    3. "Qt之Q_OBJECT详解"
    4. 一定要看 error LNK2001: 无法解析的外部符号 Qt的moc机制
  • 相关阅读:
    enumerate函数和zip函数返回的对象,都需要用list()函数转换为列表
    zip函数
    列表和元组的互相转换
    元组和列表的区别
    帮小朋友写的第一个程序
    remove del pop的区别
    如何运用Linux进行查看tomcat日志
    Linux大全
    liunx中组合查询的命令
    常见的问题
  • 原文地址:https://www.cnblogs.com/hugochen1024/p/12570465.html
Copyright © 2020-2023  润新知