QT 自定义插件问题 error: LNK2001: 无法解析的外部符号

为了重复利用已有的代码,我使用自定义插件进行开发。当每个插件独立开发时没有遇到问题,但是当插件B引用了插件A时就会在编译时报错 error: LNK2001: 无法解析的外部符号。

例如,先定义一个插件ColorPicker,用于颜色选取。关键代码如下:

复制代码
class QDESIGNER_WIDGET_EXPORT ColorPicker : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(QColor color READ getColor WRITE setColor NOTIFY colorChanged)

public:
    explicit ColorPicker(QWidget *parent = nullptr);
    ~ColorPicker();
    QColor getColor() const;
    void setColor(QColor newColor);
Q_SIGNALS:
    void colorChanged(const QColor oldColor, const QColor newColor);
protected:
    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent *event);
private:
    QScopedPointer<ColorPickerPrivate> d_ptr;
    Q_DECLARE_PRIVATE(ColorPicker)
};

该插件在APP中使用正常,但是当在另外一个插件LineProperty中使用ColorPicker 时就会报错。

复制代码
class QDESIGNER_WIDGET_EXPORT LineProperty : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(Qt::PenStyle lineStyle READ lineStyle WRITE setLineStyle NOTIFY lineStyleChanged FINAL);
    Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged FINAL);
    Q_PROPERTY(QColor lineColor READ lineColor WRITE setLineColor NOTIFY lineColorChanged FINAL);
public:
    explicit LineProperty(QWidget *parent = nullptr);
    ~LineProperty();
    Qt::PenStyle lineStyle() const;
    void setLineStyle(Qt::PenStyle newLineStyle);
    qreal lineWidth() const;
    void setLineWidth(qreal newLineWidth);
    QColor lineColor() const;
    // 在UI中使用了ColorPicker 插件
    void setLineColor(const QColor &newLineColor);

Q_SIGNALS:
    void linePropertyChanged(Qt::PenStyle style, QColor Color, qreal width);
    void lineStyleChanged(Qt::PenStyle style);
    void lineWidthChanged(qreal width);
    void lineColorChanged(QColor color);
protected:
    bool eventFilter(QObject *watched, QEvent *event) override;
private slots:
    void on_lineStyle_currentIndexChanged(int index);
    void on_lineColor_colorChanged(const QColor &oldColor, const QColor &newColor);
    void on_lineWidth_valueChanged(int arg1);
private:
    QScopedPointer<LinePropertyPrivate> d_ptr;
    Q_DECLARE_PRIVATE(LineProperty)
    Q_DISABLE_COPY(LineProperty)
};

网上大部分解决方法是这样的:

如果用到信号槽但类的定义没有放在.h文件中, qmake不会自动调moc, 你就需要写#include "moc_ColorPicker.cpp"告诉qmake你有文件需要moc

经过验证,在LineProperty .cpp文件末尾追加#include "moc_ColorPicker.cpp" 确实没有再报错。

实际上是编译器在LINK这个环节没有找到ColorPicker库文件,但是在pro文件中已经配置LIBS += -L$$OUT_PWD/../ColorPicker/release/ -lcolorpickerplugin

问题只可能是ColorPicker.h文件的定义问题。

ColorPicker类定义使用了QDESIGNER_WIDGET_EXPORT 宏,该宏用于将自定义组件类从插件导出给 Qt Designer 使用。查看QDESIGNER_WIDGET_EXPORT 的定义如下:

复制代码
#if defined(QDESIGNER_EXPORT_WIDGETS)
#  define QDESIGNER_WIDGET_EXPORT Q_DECL_EXPORT
#else
#  define QDESIGNER_WIDGET_EXPORT Q_DECL_IMPORT
#endif

LineProperty 引入ColorPicker.h文件时QDESIGNER_WIDGET_EXPORT 仍然解释为Q_DECL_EXPORT,从而导致ColorPicker库文件没有被导入到LineProperty ,所以LINK时会报错。

只需要修改ColorPicker.h文件定义,使用ColorPicker 专属的COLOR_PICKER_EXPORT即可:

复制代码
#if defined(COLOR_PICKER_LIB)
#define COLOR_PICKER_EXPORT Q_DECL_EXPORT
#else
#define COLOR_PICKER_EXPORT Q_DECL_IMPORT
#endif
class COLOR_PICKER_EXPORT ColorPicker : public QWidget
{
   ...略
};

参考:
error LNK2001: 无法解析的外部符号 Qt的moc机制
vs+qt error LNK2001: 无法解析的外部符号 "public: static struct QMetaObject 。。

相关推荐
码客-ygluu6 小时前
一个通用游戏数据服务器
c++·架构
another heaven6 小时前
【C/C++ Ranges 是零开销抽象吗?拆开管道、惰性求值和编译期膨胀】
c语言·开发语言·c++
YLCHUP9 小时前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论
xiaoye-duck9 小时前
《C++ 项目:手写大模型接入 SDK》会话模块整合:内存 SessionManager 与 DataManager 持久化联动
开发语言·数据库·c++·语言模型
思麟呀10 小时前
背包DP(01背包+完全背包)
c++·算法
旖旎夜光11 小时前
【C++ 基础入门】C++11 新特性(中):右值引用、移动语义与完美转发
开发语言·c++·笔记·学习
ShineWinsu11 小时前
对于Qt:QTabWidget常见属性的解析
开发语言·数据库·c++·qt·浏览器·qtabwidget·标签页
俊俊几年的13 小时前
动态规划(Dynamic Programming)详解:从入门到 LeetCode Hot 100
linux·c++·算法·leetcode·嵌入式·动态规划·c
老歌老听老掉牙1 天前
案例 7:二维 Rosenbrock 函数最小值(香蕉函数)
c++·pso
Severus_black1 天前
【C++初阶】Stack、Queue算法题大练兵!
c语言·c++·算法·stl