Qt 链接器错误:未定义对类方法的引用

Qt 链接器错误:未定义对类方法的引用,qt,qt5,qwidget,moc,qlayout,Qt,Qt5,Qwidget,Moc,Qlayout,我有以下非常简单的问题: 我有 #ifndef ABSTRACTWIDGET_H #define ABSTRACTWIDGET_H #include <QWidget> #include <QVariant> namespace Ui { class AbstractWidget; } class AbstractWidget : public QWidget { Q_OBJECT public: explicit AbstractWidget(con

我有以下非常简单的问题:

我有

#ifndef ABSTRACTWIDGET_H
#define ABSTRACTWIDGET_H

#include <QWidget>
#include <QVariant>

namespace Ui {
  class AbstractWidget;
}

class AbstractWidget : public QWidget
{
  Q_OBJECT

public:
  explicit AbstractWidget(const QString &name, QWidget *parent = 0);
  ~AbstractWidget();

  QString getName();

  virtual void setValue(const QVariant & value);

protected:
  Ui::AbstractWidget *ui;

};

#endif // ABSTRACTWIDGET_H
\ifndef ABSTRACTWIDGET\u H
#定义抽象控件
#包括
#包括
名称空间用户界面{
类抽象控件;
}
类AbstractWidget:公共QWidget
{
Q_对象
公众:
显式AbstractWidget(常量QString&name,QWidget*parent=0);
~AbstractWidget();
QString getName();
虚拟无效设置值(常量变量和值);
受保护的:
Ui::AbstractWidget*Ui;
};
#endif//ABSTRACTWIDGET\u H

\ifndef滑动窗口
#定义滑动窗口
#包括“abstractwidget.h”
#包括
类SliderWidget:PublicAbstractWidget
{
Q_对象
公众:
显式SliderWidget(常量QString&name、int-min、int-max、QWidget*parent=0);
~SliderWidget();
无效设置值(常量变量和值);
私人:
QSlider*滑块;
};
#endif//SLIDERWIDGET\u H
我刚刚在super class Abstractwidget中将setValue设置为虚拟,这会删除以下链接器错误:

moc_abstractwidget.cpp:-1:Fehler:未定义对的引用 `AbstractWidget::setValue(QVariant const&)'

collect2.exe:-1:Fehler:错误:ld返回1退出状态

重建和清理一切都无济于事。为什么它无法链接

  • 抽象是一个不好的名词文化,对不起我的不好。把它看作是一个超类(不是抽象的),从中派生出其他类。

  • 我动态地在MainWindow::Ui::QVBoxLayout中注入这些AbstractWidget类(例如,我还有多个SliderWidget和ColorPickerWidget:public AbstractWidget)。我只是想保持简单

  • 为什么要派生?我有多个从AbstractWidget类派生的QWidget(除了SliderWidget)。它们都有一个QString名称。我想在基类==>AbstractWidget中提供这个名称

  • 为什么虚拟void setValue():每个派生类都有一些功能,如滑块、颜色选择器等。我在每个派生类中实现一个setValue(QVariant),以便颜色选择器设置QColor(QVariant::toString()),滑块Widget使用setValue(QVariant::toInt())设置sliderValue,等等。。 setValue在任何地方都是公共的(虚拟基类和派生实现)


  • 该方法是在cpp文件中实现的吗?另外,我看到您继承了一个小部件,使用UI设计器构建。我不确定这是否合法,我还没有尝试过,但这听起来可能是一个问题源。@ddriver它没有在定义为virtual的超类中实现。在派生类中实现了它,但不是使用完全相同的参数签名@ddriver在我添加并实现虚拟void setValue()之前,它工作正常。@RalfWickum-如果不想为虚拟方法提供实现,应将其标记为抽象,并使用
    =0在末尾。这将防止编译器抱怨它找不到它的定义。该方法是在cpp文件中实现的吗?另外,我看到您继承了一个小部件,使用UI设计器构建。我不确定这是否合法,我还没有尝试过,但这听起来可能是一个问题源。@ddriver它没有在定义为virtual的超类中实现。在派生类中实现了它,但不是使用完全相同的参数签名@ddriver在我添加并实现虚拟void setValue()之前,它工作正常。@RalfWickum-如果不想为虚拟方法提供实现,应将其标记为抽象,并使用
    =0在末尾。这将防止编译器抱怨找不到其定义。
    
    #ifndef SLIDERWIDGET_H
    #define SLIDERWIDGET_H
    
    #include "abstractwidget.h"
    
    #include <QSlider>
    
    class SliderWidget : public AbstractWidget
    {
      Q_OBJECT
    
    public:
      explicit SliderWidget(const QString & name, int min, int max, QWidget *parent = 0);
      ~SliderWidget();
    
      void setValue(const QVariant & value);
    
    private:
      QSlider * slider;
    
    };
    
    #endif // SLIDERWIDGET_H