Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: d13mon от Февраль 25, 2013, 13:05



Название: Как разместить код Qt-класса в main.cpp?
Отправлено: d13mon от Февраль 25, 2013, 13:05
День добрый,

Давно интересует один вопрос. Создаем простейший проект (использую MSVC2010) Qt Application - там класс производный от QWidget (в 2-х файлах - .h и .cpp) и main.cpp. Компилируем, собираем, всё ок. Затем пихаем весь код в main.cpp:
Код:
#include <QtGui/QWidget>
#include <QtGui/QApplication>

class TestWidget : public QWidget
{
Q_OBJECT

public:
TestWidget(QWidget *parent = 0, Qt::WFlags flags = 0)
: QWidget(parent, flags)
{
}
~TestWidget(){}
};

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TestWidget w;
w.show();
return a.exec();
}

и линковщик выдает странные ошибки, характерные для случаев, когда с  Q_OBJECT что-то не так.
Код:
main.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall TestWidget::metaObject(void)const " (?metaObject@TestWidget@@UBEPBUQMetaObject@@XZ)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall TestWidget::qt_metacast(char const *)" (?qt_metacast@TestWidget@@UAEPAXPBD@Z)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall TestWidget::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@TestWidget@@UAEHW4Call@QMetaObject@@HPAPAX@Z)

Кто-нибудь знает, из-за чего это и как побороть?


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: Пантер от Февраль 25, 2013, 13:07
#include "main_moc.cpp" в самом низу main.cpp сделай.


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: GreatSnake от Февраль 25, 2013, 13:10
прогони main.cpp через moc:
Код
DOS
moc -o moc_main.cpp main.cpp
Полученный moc_main.cpp в ставь в самом конце main.cpp через
Код
C++ (Qt)
#include "moc_main.cpp"


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: d13mon от Февраль 25, 2013, 13:11
#include "main_moc.cpp" в самом низу main.cpp сделай.

О,спасибо

Правда, помогло не #include "main_moc.cpp", а #include "main.moc"


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: d13mon от Февраль 25, 2013, 13:19
прогони main.cpp через moc:
Код
DOS
moc -o moc_main.cpp main.cpp
Полученный moc_main.cpp в ставь в самом конце main.cpp через
Код
C++ (Qt)
#include "moc_main.cpp"

Попробовал так тоже, пишет
Код
DOS
D:\WORK\PROJECTS\CPlusPlus\QT\Qt_training\TestWidget>moc -o moc_main.cpp main.cpp
main.cpp(0): Note: No relevant classes found. No output generated.

На выходе получаю пустой moc_main.cpp


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: Alex Custov от Февраль 25, 2013, 15:10
прогони main.cpp через moc:

если просто добавить #include "main.moc", то qmake сам определит, что нужно сгенерить main.moc и создаст правила.


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: schmidt от Февраль 26, 2013, 11:02
Затем пихаем весь код в main.cpp.

У меня только один к вам вопрос: зачем? ???


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: VozaMFC от Февраль 26, 2013, 17:50
Затем пихаем весь код в main.cpp.

У меня только один к вам вопрос: зачем? ???

Что бы в одном файле все было.


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: Bepec от Февраль 26, 2013, 18:51
И получаем дикую головную боль при использовании другой IDE  :D

PS к примеру тот же VS  :D


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: twp от Февраль 26, 2013, 22:52
А какие проблемы при использовании в VS такого подхода?


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: Bepec от Февраль 27, 2013, 06:54
VS создаёт моки и прочее в процессе компиляции кода. Причём местонахождение папки для генерируемых файлов меняется в настройках проекта. Т.е. мне например удобно, что они сразу улетают в темп и не мучают меня своим присутствием в папке с исходниками.

А раз их местонахождение может измениться за 5 секунд, значит чтобы их найти, необходимо прописывать абсолютные пути для их подключения.

Проще выражаясь - создаётся фиг пойми где, а даже если и пойми где, нужен абсолютный путь.

PS кто-то скажет - так тебе и надо, а я скажу - нафиг мне файл, который каждый раз заново создаётся, в папке с проектом.


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: schmidt от Февраль 27, 2013, 09:10
Что бы в одном файле все было.

 ;D ;D 5 баллов!

Запихнув все классы проекта в один файл вы не получите ничего, кроме головной боли. С таким подходом у вас получится не то что винегрет вместо проекта, а каша из 10 круп. Как только число ваших классов приблизится к десятку, а код каждого класса перестанет умещаться в окне редактора, вы проклянёте себя самыми последними словами после 1-2х дней работы с этой высокохудожественной свалкой :)


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: xokc от Февраль 27, 2013, 09:21
Запихнув все классы проекта в один файл вы не получите ничего, кроме головной боли. Как только число ваших классов приблизится к десятку вы проклянёте себя самыми последними словами после 1-2х дней работы с этой высокохудожественной свалкой :)
Как легко вешать ярлыки. А может у него НИКОГДА в этом проекте не будет десятка классов? Будьте менее категоричны.


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: GreatSnake от Февраль 27, 2013, 10:52
Не понимаю "непониманий" schmidt и Bepec.
Для серьёзных проектов, конечно, сей случай навряд ли подойдёт.
Но для test-case-ов и для обкатки какого-нибудь случая считаю такой подход самым оптимальным.
Сам здесь уже не первый год пользуюсь им для рабочих примеров.


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: Bepec от Февраль 27, 2013, 10:55
Выражу мысль так.

Для использующий креатор - это, без сомнения, удобное решение для тестовых проектиков.

Для тех, кто НЕ использует креатор - это решение будет удобно лишь после настройки IDE и, возможно, шаманства с путями.

Для тех, кто соберётся передавать проект кому-то - это создание проблем.


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: GreatSnake от Февраль 27, 2013, 11:04
Про публичность вроде как разговор не стоял вообще.
На линуксе для таких случаев мне достаточно любого редактора и командной строки:
Код
Bash
moc -o moc_test1.cpp test1.cpp && g++ -O0 -g3 -o test1 test1.cpp `pkg-config --cflags QtGui` `pkg-config --libs QtGui` && ./test1


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: twp от Февраль 27, 2013, 12:52
VS создаёт моки и прочее в процессе компиляции кода. Причём местонахождение папки для генерируемых файлов меняется в настройках проекта. Т.е. мне например удобно, что они сразу улетают в темп и не мучают меня своим присутствием в папке с исходниками.

А в чем проблема? Сгенерированные исходники VS отображает в Generated Files, ресурсы - в Resource Files, а сами исходники в Source Files. Большого неудобства я в этом не вижу. Или я что-то недопонимаю?

А раз их местонахождение может измениться за 5 секунд, значит чтобы их найти, необходимо прописывать абсолютные пути для их подключения.

Проще выражаясь - создаётся фиг пойми где, а даже если и пойми где, нужен абсолютный путь.
Хм, не один год пользуюсь VS и никогда не приходилось прописывать абсолютные пути или что-то подобное. Можно по-подробнее об этой проблеме?

И ничего плохого не вижу, использовать такой подход для небольшого приложения, или одного класса, который используется только в main.cpp.
Вот список демок и примеров, что поставляются вместе c Qt:

demos\embedded\flickable\main.cpp
demos\glhypnotizer\main.cpp
examples\activeqt\comapp\main.cpp
examples\activeqt\simple\main.cpp
examples\activeqt\webbrowser\main.cpp
examples\animation\animatedtiles\main.cpp
examples\animation\appchooser\main.cpp
examples\animation\moveblocks\main.cpp
examples\animation\states\main.cpp
examples\tutorials\gettingStarted\gsQt\part3\main.cpp
examples\tutorials\gettingStarted\gsQt\part4\main.cpp
examples\tutorials\gettingStarted\gsQt\part5\main.cpp
examples\widgets\validators\main.cpp
examples\graphicsview\weatheranchorlayout\main.cpp
examples\network\bearercloud\main.cpp
examples\network\download\main.cpp
examples\statemachine\factorial\main.cpp
examples\statemachine\trafficlight\main.cpp

Неужели разоработчики Qt не в курсе, что это сплошная "головная боль"?


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: Bepec от Февраль 27, 2013, 13:20
Я имею в виду, что у меня генерейтед файлы в 50% проектов улетают в e:\temp\. В оставшихся файлы улетают в %папкаПроекта%/tresh/.

Если я туды подключу #include <moc_main.cpp> у меня ничего не соберётся :D Если я напишу #include <e:\temp\moc_main.cpp> то будет работать в 50% случаев.

И :

1) не спорю, удобно это тем, кто использует Qt Creator.
2) не спорю, тролли, использующие Qt Creator для создания примеров, тоже понимают что им удобно.
3) не спорю, если я когда нибудь начну использовать Qt Creator, это будет удобно :D

НО:
1) это неудобно мне в VS, ибо настройки IDE могут меняться в зависимости от проектов :D
2) это неудобно в VS, когда используются пропертишиты (комплекс настроек для проектов, устанавливающий единообразные настройки для IDE у всех разработчиков)
3) да и тупо неудобно, потому что папка generated files, в которую по умолчанию кладутся файлы по умолчанию не входит в пути для include.


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: twp от Февраль 27, 2013, 13:55
Я имею в виду, что у меня генерейтед файлы в 50% проектов улетают в e:\temp\. В оставшихся файлы улетают в %папкаПроекта%/tresh/.

Если я туды подключу #include <moc_main.cpp> у меня ничего не соберётся :D Если я напишу #include <e:\temp\moc_main.cpp> то будет работать в 50% случаев.

Пахнет какой-то ерундой. Неужели чтоб собрать любой из примеров в VS, нужно где-то прописывать абсолютный путь?
Да и qmake переменные     
    MOC_DIR
    OBJECTS_DIR
    UI_DIR
    RCC_DIR
указывают на e:\temp\? Тогда опять же, ничего явно прописывать не нужно.

И тогда такой вопрос, как происходит открытие Qt-проекта в VS?


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: Bepec от Февраль 27, 2013, 14:45
Хм. Собрал примеры. Был неправ.

Не компилится когда пытаешься приписать #include <moc_class.h>. При прописи же #include <main.moc> всё стабильно и нормально.

А открытия Qt проекта не происходит. Происходит генерация sln файла из pro. Подключаемые модули и прочая устанавливаются в конфигурацию проекта.



Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: schmidt от Февраль 27, 2013, 17:14
Привычка же - вторая натура :) Как привыкнешь с самого начала - так и будешь делать на автомате.

Цитировать
А может у него НИКОГДА в этом проекте не будет десятка классов?

Тоже весьма категоричное утверждение, смею заметить  ::)  :)


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: xokc от Март 01, 2013, 09:23
Цитировать
А может у него НИКОГДА в этом проекте не будет десятка классов?
Тоже весьма категоричное утверждение, смею заметить  ::)  :)
Сочетание слов "может" и в "этом проекте" не подразумевает категоричного толкования.


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: schmidt от Март 01, 2013, 10:35
Я бы не стал заранее "хоронить" свои маленькие тестовые проекты-заготовки подобными деяниями - а вдруг автору КОГДА-НИБУДЬ понадобится функциональность этого проекта и он пожелает просто встроить его в другой проект? В том и соль - не собирать 200 велосипедов на протяжении всей жизни, а иметь собственную подборку небольших рабочих проектов для повторного использования. Не вижу ни одной очевидной причины, почему "тестовый" код собственных примеров нужно обязательно выполнять в стиле *овнокода :D. Хорошие привычки стоит набирать с самого начала пути :)


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: xokc от Март 01, 2013, 12:18
Я бы не стал заранее "хоронить" свои маленькие тестовые проекты-заготовки подобными деяниями - а вдруг автору КОГДА-НИБУДЬ понадобится функциональность этого проекта и он пожелает просто встроить его в другой проект?
А я предпочитаю решать проблемы по мере их поступления и «не множить сущее без необходимости», но допускаю, при этом, наличие других подходов к разработке (например, подобного Вашему) поэтому и рекомендую не комментировать чужие вопросы в стиле
;D ;D 5 баллов!


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: schmidt от Март 01, 2013, 14:11
«не множить сущее без необходимости»

Насколько всем известно, Creator автоматом создаёт по отдельному файлу на каждый класс ;) Силком пихать их в один файл - не это ли излишние усилия? :)


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: sergek от Март 01, 2013, 19:48
Силком пихать их в один файл - не это ли излишние усилия? :)
А мы пишем на C++ или Qt++?  :-\


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: schmidt от Март 08, 2013, 18:20
А что за язык такой, Qt++ ?  ;) QML?


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: sergek от Март 09, 2013, 13:47
А что за язык такой, Qt++ ?  ;)
Это "язык", в котором "Силком пихать их в один файл" требует "излишние усилия"  ;)
C++ это позволяет.


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: Alex Custov от Март 27, 2013, 17:17
Так как правильно прописывать?
#include "main.moc" - no such file,
moc.exe -o moc_main.cpp main.cpp - Note: No relevant classes found. No output generated
(5.0.1 mingw, настройки по умолчанию)

Либо ты что-то сделал неправильно, например, не указал Q_OBJECT, либо тебе и не нужен moc и соответствующий #include добавлять не нужно.


Название: Re: Как разместить код Qt-класса в main.cpp?
Отправлено: Alex Custov от Март 27, 2013, 22:05
зачем? Если необходимости в нём нет, то и создавать не нужно, и писать #include "main.moc" тоже