Почему нельзя написать класс QWidget в main.cpp?

Обновлять:

Если я удалю Q_OBJECT и не использую SLOTSINGAL, просто используйте connect() следующим образом:

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

мой код будет работать без предупреждений и ошибок.


Я хочу написать небольшой код, чтобы проинструктировать некоторые классы, поэтому я стараюсь упростить свой код. Но я столкнулся с некоторыми странными вещами. Я не могу записать простой widget в свой main.cpp. Если я напишу виджет на mywidget.cpp и mywidget.h, программа будет работать нормально. Если я хочу записать виджет в main.cpp, что мне делать?

Это мой код.

#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();
}

И информация об ошибке:
Почему нельзя написать класс QWidget в main.cpp?

Я бы сказал, что это проблема MOC: он работает только с заголовочными файлами. Но макросу Q_OBJECT для работы нужен MOC. Если убрать макрос Q_OBJECT, все будет нормально

Xatyrian 11.04.2018 11:04

Да. Удалите Q_OBJECT, код работает нормально. Но если я удалю его, я не смогу использовать connect(), а это полезная функция, которая мне нужна.

JosanSun 11.04.2018 11:07

Конечно, предлагаю вам взглянуть на этот вопрос

Xatyrian 11.04.2018 11:10

Объявления должны быть в файле .hpp или .h, а не в .cpp.

user3606329 11.04.2018 11:23
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
113
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Добавьте следующую строку в конец main.cpp и перезапустите qmake:

#include "main.moc"

Это вызовет инструмент moc для вашего main.cpp. Он генерирует определения метаобъектных функций для вашего класса Widget, разрешая ошибки компоновщика при перестроении.

Как указано в документация:

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.

Таким образом, поместите объявление класса в файл заголовка (например, widget.h), а определение класса в исходный файл с тем же именем (например, widget.cpp).

Если вы все еще хотите, чтобы он работал с сигналами, вы можете удалить макрос Q_OBJECT и использовать QObject::connect()

Например:

#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();
}

Тестирую на Qt5.9.4

Когда я удаляю QObject::, программа тоже работает нормально.

JosanSun 11.04.2018 11:51

Другие вопросы по теме