2

Update:

If I delete Q_OBJECT, and I do not use SLOT SINGAL, just use connect() like this:

connect(this, &QWidget::destroyed, this, &QWidget::myslot),

my code will run well without any warnings and errors.


I want to write a little code to instruct some classes, so I try to simplify my code. But I encountered some strange things. I cannot write a simple widget in my main.cpp. If I write the widget in mywidget.cpp and mywidget.h, the program runs well. If I want to write the widget in the main.cpp, what should I do?

This is my code.

#include <QApplication>
#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
};

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
}

Widget::~Widget()
{

}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

And the error information is:
error information

JosanSun
  • 339
  • 2
  • 12
  • 1
    I would say it's an issue with the MOC: it only runs on header files. But the Q_OBJECT macro needs the MOC to work. If you remove the Q_OBJECT macro, everything will be fine – Xatyrian Apr 11 '18 at 09:04
  • Yes. remove `Q_OBJECT`, the code runs well. But if I remove it, I cannot use the `connect()`, which is a useful function I need – JosanSun Apr 11 '18 at 09:07
  • 1
    Sure, I suggest you look at this [question](https://stackoverflow.com/questions/34928933/why-is-important-to-include-moc-file-at-end-of-a-qt-source-code-file) – Xatyrian Apr 11 '18 at 09:10
  • Declarations should be in the `.hpp` or `.h` file, not in the `.cpp`. – user3606329 Apr 11 '18 at 09:23

3 Answers3

2

Add following line to the end of main.cpp and rerun qmake:

#include "main.moc"

That will invoke moc tool for your main.cpp. It generates meta-object function definitions for your Widget class resolving your linker errors when you rebuild.

talamaki
  • 5,324
  • 1
  • 27
  • 40
2

As stated in documentation:

Whenever qmake is run, it parses the project's header files and generates make rules to invoke moc for those files that contain a Q_OBJECT macro.

Thus, put the class declaration in a header file (e.g. widget.h) and the class definition in a source file with the same name (e.g. widget.cpp).

p-a-o-l-o
  • 9,807
  • 2
  • 22
  • 35
1

If you still want to make it work with signals you can remove the Q_OBJECT macro and use the QObject::connect()

for example:

#include <QApplication>
#include <QWidget>
#include <iostream>

class Widget : public QWidget
{
    //Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
};


Widget::Widget(QWidget *parent) : QWidget(parent)
{
    // say bey
    QObject::connect(this,&Widget::destroyed,
                     [](){std::cout<<"bye"<<std::endl;});
}

Widget::~Widget()
{

}


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Widget w;
    w.show();

    return a.exec();
}

I test it on Qt5.9.4

Simon
  • 1,522
  • 2
  • 12
  • 24