【问题标题】:Adding signals to class that inherit from QGraphicsScene向继承自 QGraphicsScene 的类添加信号
【发布时间】:2010-11-10 18:31:08
【问题描述】:

我想向继承自 QGraphicsScene 的类添加信号。

signals:
    void update(std::vector< std::vector<int> > board);

当我这样做时,Qt Creator 会警告我我忘记了 Q_OBJECT 宏。但是我在某处读到,因为QGraphicsScene 不是从QObject 继承的,所以我不应该把它放在我的类定义中。但是信号需要这个宏。

如何向不继承自 QObject 的类添加信号?


boardgui.h

#ifndef BOARDGUI_H
#define BOARDGUI_H
#include <QGraphicsView>
#include <QGraphicsScene>

class BoardGUI : public QGraphicsScene
{
    Q_OBJECT
public:
    BoardGUI(QGraphicsView*& view, int dimension);
    ~BoardGUI();
    void buildBoard();
signals:
    void update(std::vector< std::vector<int> > board);
private:
    int dimension;
    QGraphicsView* view;
};

#endif // BOARDGUI_H

【问题讨论】:

    标签: c++ qt graphics qobject


    【解决方案1】:

    根据要求重新发布为答案:

    update() 是你的信号吗?您是否尝试自己实现信号?如果是,请不要这样做,信号由 moc 定义。

    【讨论】:

      【解决方案2】:

      QGraphicsScene 确实继承自 QObject。您可以查阅文档。 http://doc.qt.io/qt-5/qgraphicsscene.html

      【讨论】:

      • 那么我应该可以添加宏了吗?如果这样做,我会收到以下编译器错误:img29.imageshack.us/img29/7995/errorsv.jpgWhat is a vtable?
      • 我做了一些研究...如果 vtable 如果给出错误,则运行时绑定一定有问题。
      • 确保在进行此类更改后进行全面清理和重建。当 QtCreator 错误地缓存了一些关于什么有信号和什么没有信号的旧信息时,我已经看到它感到困惑。此外,请确保 .pro 文件的标题部分正确,并研究 moc 的行为以确保 .pro 文件能够满足其需要。
      • 我没有手动修改我的 .pro 文件,所以除非 Qt Creator 出现故障,否则应该没问题,对吧?我进行了清理(右键单击项目,然后“清理项目”),但没有帮助。
      • @Pieter:也许是在黑暗中拍摄,但一定要运行 qmake(它是 QtCreator 构建菜单中的一个选项),moc 需要在 Q_OBJECT 类上运行,QtCreator 可能忘记了:)。
      【解决方案3】:

      Vtables 与虚函数有关。当您遇到Undefined reference to vtable 之类的错误时,它无法找到虚函数的实现(我认为)。你实现了所有的功能吗?也许您不应该使用virtual 关键字?还是反过来?

      另外,你说你想添加一个信号,但是你的代码块显示了一个槽?你能多展示一下你的班级吗?

      【讨论】:

      • gcc 中对 vtable 错误的未定义引用确实最常见的原因是缺少类中虚函数的实现。
      • 哎呀,是的,我确实打算使用信号。我仍然遇到同样的错误。我将类的头文件添加到我的问题中。
      • 尝试将signals: 更改为private signals:public signals:,具体取决于您是否希望update 信号公开。虽然,我认为它可能只是从上面继承了private:
      • 私有信号:,公共信号:不管是语法还是语义都不起作用。信号是“受保护”的定义。
      • update() 是你的信号吗?您是否尝试自己实现信号?如果是,请不要这样做,信号由 moc 定义。
      【解决方案4】:

      如果您之前没有在项目中使用 Q_Object 实现任何类并且您自己添加了 Q_OBJECT 行,则会收到 vtable 错误。如果您将另一个 c++ 类添加到从 QObject 继承的项目中,那么您就可以摆脱这个问题。如果您不需要它,您可以删除您创建的此类。我不确定为什么会发生这种情况,但这是解决问题的简单方法。也许创作者在 . pro 文件,当你添加一个继承自 qobject 的类时。

      【讨论】:

        【解决方案5】:

        你实现了你的析构函数吗?如果不是,请尝试将~BoardGUI(); 更改为~BoardGUI(){};

        【讨论】:

        • 结尾的“;”没用,并且会根据您的编译器发出警告。
        • 是的,我已经在boardgui.cpp中实现了析构函数。
        【解决方案6】:

        您是否已将 boardgui.h 添加到 MOC 预处理器的文件列表中?任何使用 QObject 和 Signals/Slots 的类都需要通过 Meta-Object Compiler,以便生成信号背后的实际代码。

        我不确定 Qt Creator 是否会自动处理这个问题。

        【讨论】:

        • 我认为它确实会自动处理。来自文档:除了最简单的测试程序之外,建议您自动运行 moc。通过在程序的 makefile 中添加一些规则,make 可以在必要时负责运行 moc 并处理 moc 输出。我们建议使用 qmake makefile 生成工具来构建您的 makefile。这个工具会生成一个 makefile 来完成所有必要的 moc 处理。
        • @Pieter 有趣。这是否包括根据内容确定哪些头文件实际上需要生成 MOC?或者它只是MOC他们所有人?我使用 CMake 生成构建文件,并且可以调用 MOC 宏,但我仍然需要向它们传递需要生成 MOC 的头文件列表
        【解决方案7】:

        您只需要自己继承QObject

        boardgui.h

        #ifndef BOARDGUI_H
        #define BOARDGUI_H
        #include <QGraphicsView>
        #include <QGraphicsScene>
        
        class BoardGUI : public QObject, public QGraphicsScene
        {
            Q_OBJECT
        public:
            BoardGUI(QGraphicsView*& view, int dimension);
            ~BoardGUI();
            void buildBoard();
        signals:
            void update(std::vector< std::vector<int> > board);
        private:
            int dimension;
            QGraphicsView* view;
        };
        
        #endif // BOARDGUI_H
        

        如果您使用的是Qt Creator,则不必担心moc,一切都应由Qt Creator处理。

        【讨论】:

          猜你喜欢
          • 2014-02-25
          • 2017-09-18
          • 2015-12-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-05-29
          相关资源
          最近更新 更多