【问题标题】:Inheriting subclasses can not use Q_OBJECT继承子类不能使用Q_OBJECT
【发布时间】:2013-12-17 12:56:58
【问题描述】:

我的类有一个大问题:我将在我的子类中使用Q_OBJECT 宏。但是如果我在我的子类中定义Q_OBJECT,它会抛出一个异常。这是一个例外:

undefined reference to `vtable for SubClassOne'
undefined reference to `vtable for SubClassTwo'

我的SubClassOneSubClassTwo 继承自BaseClass

这里有一些代码:(所有#includes 都是正确的)

\\baseclass.h
class BaseClass
{
public:
BaseClass(QWidget *widget=0);
QHBoxLayout *mainLayout;
};

\\subclassone.h
class SubClassOne : public BaseClass, public QWidget
{
 Q_OBJECT
public:
   explicit SubClassOne(QWidget *widget=0);
};

\\subclasstwo.h
class SubClassTwo : public BaseClass, public QDialog
{
 Q_OBJECT
public:
    explicit SubClassTwo(QWidget *dialog=0);
};

.cpp 文件来了

//baseclass.cpp
BaseClass::BaseClass(QWidget *widget)
{
 mainLayout = new QHBoxLayout();
}

//subclassone.cpp
SubClassOne::SubClassOne(QWidget *widget):BaseClass(widget)
{
 setWindowTitle("Widget");
}

//subclasstwo.cpp
SubClassTwo::SubClassTwo(QWidget *dialog):BaseClass(dialog)
{
setWindowTitle("Dialog");

QPushButton *btn = new QPushButton();
QObject::connect(btn,SIGNAL(clicked()),SLOT(close()));
mainLayout->addWidget(btn);
setLayout(mainLayout);
}

main.cpp

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SubClassTwo *s = new SubClassTwo();
s->show();
return a.exec();
}

如何在我的子类中使用Q_OBJECT

【问题讨论】:

  • 3) 你在标题上运行 moc
  • 另外,QObject(或从QObject 派生的基类)必须是基类列表中的第一个。而且您不能多次或虚拟地继承QObject
  • 对不起我的错误,我忘记了,已经编辑了我的帖子,你能给我一个包含 ..moc 文件的例子吗?使用 Qt5
  • @Angew:这对 Qt 5 来​​说不是这样......
  • @LaszloPapp 再见!谢谢(你的)信息。我现在坚持使用 Qt4,但至少我会知道隧道尽头有光明。

标签: c++ qt qobject qtcore


【解决方案1】:

您的 Q_OBJECT 放置在您的代码中很好。

您遇到的问题是您忘记在源代码中包含生成的 moc 文件,例如:

baseclass.cpp(在文件末尾)

#include "baseclass.moc"

subclassone.cpp(在文件末尾)

#include "subclassone.moc"

subclasstwo.cpp(在文件末尾)

#include "subclasstwo.moc"

您需要确保 moc 正在为您生成这些文件。你还没有展示你的构建系统。

另外,请确保每个“Q_OBJECT”类都有一个头文件和源文件。这不是绝对必要的,但这是一个很好的做法。

您当然也可以在链接时解决该问题,但您需要执行其中任何一项。

此外,一旦你有多重继承,至少在 Qt 4 中,你需要首先从 QObject 子类继承,在你的例子中是 QWidget。您可以在下面找到正确的继承。

subclassone.h

class SubClassOne : public QWidget, public BaseClass

子类二.h

class SubClassTwo : public QDialog, public BaseClass

等等。希望对您有所帮助。

【讨论】:

  • 你可以让 moc 创建一个 moc_foo.cpp 并单独编译和链接
  • @ratchetfreak:是的,但显然他也没有这样做。
  • no such file or directory foo.moc
  • @user2372976:因为您需要真实的文件名,请在发表评论之前查看我更新的帖子。
  • 好的,但通常我的超类继承自 qwidget 并且这个超类可以使用 Q_OBJECT makro。子类也可以使用它。也许改变我的课程结构会更好?
【解决方案2】:

Q_OBJECT 必须是你的类中的第一个声明,并且任何继承 QObject 的类必须在列表中的第一个

class SubClassOne : public QWidget, public BaseClass
{
Q_OBJECT
public:
   explicit SubClassOne(QWidget *widget=0);
};

\\subclasstwo.h
class SubClassTwo : public QDialog, public BaseClass
{
Q_OBJECT
public:
    explicit SubClassTwo(QWidget *dialog=0);
};

您还需要在标头上运行 moc 以生成实现插槽和信号所需的代码

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 2014-05-10
    • 2011-07-21
    • 1970-01-01
    • 2017-05-24
    • 2022-11-23
    • 1970-01-01
    相关资源
    最近更新 更多