You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt使用信号槽时添加Q_OBJECT出现vtable未定义报错如何解决?

错误原因

该报错并非编译器无法识别Q_OBJECT宏,本质是qmake没有为包含Q_OBJECT宏的Test类生成对应的元对象代码,也未将生成的代码加入编译链接流程,导致类的虚函数表相关符号缺失。去掉Q_OBJECT宏后不需要额外的元对象代码,因此可以正常编译,但此时你将无法使用Qt信号槽等元对象系统特性。

解决步骤(适配mingw64 + qmake环境)
  • 方案一:标准项目结构(推荐)

    1. 拆分代码到独立头文件:你当前将所有代码写在单个.cpp文件中,qmake默认不会为单cpp内的Q_OBJECT类自动生成moc代码。将Test类的声明拆分到独立头文件test.h:
    #ifndef TEST_H
    #define TEST_H
    #include <QObject>
    #include <QMessageBox>
    
    class Test: public QObject {
      Q_OBJECT
    
    public slots:
      void message() {
        QMessageBox message;
        message.setText("Click event was triggered.");
        message.exec();
      }
    };
    #endif // TEST_H
    
    1. 修改主cpp文件为main.cpp,开头引入拆分出的头文件,移除原有的Test类声明:
    #include <QApplication>
    #include <QWidget>
    #include <QPushButton>
    #include <QGridLayout>
    #include "test.h"
    
    int main(int argc, char *argv[]) {
      QApplication app(argc, argv);
      Test test;
    
      QWidget *window = new QWidget;
      
      QGridLayout *layout = new QGridLayout(window);
    
      QPushButton *login = new QPushButton("Info");
      QObject::connect(login, SIGNAL(clicked()), &test, SLOT(message()));
    
      layout->addWidget(login, 0, 0);
    
      window->setLayout(layout);
      window->show();
    
      return app.exec();
    }
    
    1. 检查你的.pro项目配置,确保包含以下内容:
    QT += widgets
    SOURCES += main.cpp
    HEADERS += test.h
    
    1. 清理旧构建缓存重新编译:删除整个build输出目录,依次执行qmake、mingw64-make(部分环境命令为mingw32-make)即可完成编译。
  • 方案二:单文件快速调试
    如果你不想拆分文件做快速测试,可以直接在现有单cpp文件的末尾添加一行:

    #include "moc_<你的cpp文件名>.cpp"
    

    比如你的cpp文件名为main.cpp,就添加#include "moc_main.cpp",之后重新执行qmake+编译流程即可。

内容的提问来源于stack exchange,提问作者yui amanda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 02:09:03