Перейти к содержимому

Moc qt что это

  • автор:

Зачем подключают *.moc файлы в Qt?

Возможно это (и прочий вывод гугла) поможет Вам в дальнейших разборках с монстром. А вообще, *.moc это С++ текст, сгенеренный Meta-Object Compiler, moc, is the program that handles Qt’s C++ extensions.

27 июн 2013 в 6:43

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Как я понимаю, это делается тогда, когда для создания make-файлов используется не утилитка qmake, а что-то другое. Если Вы для компиляции и всего остального используете QT это делать не нужно и даже не рекомендуется. Выдержка из книжки «Макс Шлее — QT 4.5. Профессиональное программирование на C++» (стр. 66):

Созданные moc-файлы не стоит включать с помощью команды препроцессора #include «main.moc» в конец основного файла. . Лучше если они будут отдельно откомпилированы и подсоединены компоновщиком к основной программе.

Также можно привести цитатку отсюда:

The C++ source file generated by moc must be compiled and linked with the implementation of the class. If you use qmake to create your makefiles, build rules will be included that call the moc when required, so you will not need to use the moc directly.

Т.е. на мой взгляд при написании программ в QT лучше этого не делать. QT сделает все за вас.

Метаобъектный компилятор

Мета-объектная система — часть ядра Qt фреймворка для поддержки Qt расширений в С++ таких, как сигналы и слоты для коммуникации между объектами в режиме реального времени и динамических свойств системы.

Мета-объектная система содержит: класс QObject, макрос Q_OBJECT и утилиту moc(Мета-Объектный Компилятор). QObject это базовый класс для всех Qt классов. Q_OBJECT макрос используется для включения мета объектных функций в классах и на этапе компиляции moc работает как препроцессор который преобразует применения макроса Q_OBJECT в исходный код C++.

Использование мета-объектных систем прошло через некоторую критику. В документации Qt было дано несколько вещей в пользу мета-объектных систем, включая плюсы генерации кода, динамичности графических интерфейсов, автоматической связи со скриптовыми языками, не добавляя ограничений и так же хорошая, производительная разработка механизма сигналов и слотов в moc.

Ссылки [ править ]

  • «The Meta-Object System — QtCore 5.1». Qt Project. 2013-07-04. Retrieved2013-07-04.
  • «Using the Meta-Object Compiler (moc)». Qt Project. 2013-07-04. Retrieved2013-07-04.
  • «Why Does Qt Use Moc for Signals and Slots?». Qt Project. 2013-07-04. Retrieved 2013-07-04.
  • «Re-implementing Qt moc using libclang». Olivier Goffart. 2013-07-04. Retrieved 2013-07-04.

Метаобъектный компилятор

Пояснение причин и соответствующее обсуждение вы можете найти на странице Википедия:К удалению/25 июня 2012.
Пока процесс обсуждения не завершён, статью можно попытаться улучшить, однако следует воздерживаться от переименований или немотивированного удаления содержания, подробнее см. руководство к дальнейшему действию.
Не снимайте пометку о выставлении на удаление до окончания обсуждения. Администраторам: ссылки сюда, история (последнее изменение), журналы, удалить .

  • Дата постановки шаблона: 5 августа 2010

Метаобъектный компилятор (сокр. МОК) (от англ.Meta Object Compiler или MOC) предназначен для генерации метаобъектного сопутствующего кода на основе библиотеки Qt. МОК считывает одно (или более) определение C++ класса из заголовочного файла языка C++ или исходного файла программы и генерирует один исходный файл на языке С++, содержащий метаобъектную информацию для классов. Получившийся исходный файл, сгенерированный МОК, должен быть скомпилирован и слинкован с реализацией класса (или может быть включен при помощи инструкции #include в исходный файл с описанием класса). В случае применения программы qmake для создания make-файлов, правила сборки, вызывающие МОК при необходимости, будут автоматически включены, поэтому напрямую вызывать МОК не требуется. Коротко говоря, метаобъектная система — структура, используемая библиотекой Qt для компонентного программирования и необходимая для типовой информации при запуске. она добавляет свойства и наследует информацию в (некоторые) классы, а также реализует новый тип взаимодействия между такими сущностями подобных классов, взаимосвязь, основанную на принципе сигнал-слот.

Параметры и возможности

Параметр Описание
-o

Записывает выводимую информацию в файл в более подробном виде, чем в stdout.
-f Принудительная генерация инструкции #include в вывод. Является установленным режимом по умолчанию для файлов, чье имя подходит под регулярное выражение .[hH][^.]* (т.е. расширение срабатывает для H или h). Этот параметр полезен только если используются заголовочные файлы, не соответствующие соглашениям о стандартном именовании.
-i Не генерировать инструкции #include в вывод. Этот режим может быть полезен для запуска МОК для работы с C++ файлом, содержащим одно или более объявлений класса. В этом случае следует подключить метаобъектный код при помощи инструкции #include в файле .cpp (смотри примеры использования ниже). В случае указания обоих параметров (-f и -i) приоритет получает последний.
-nw Не выводить никаких предупреждений (не рекомендуется использовать).
-ldbg Запись потока отладочной информации в stdout.
-p

Заставляет МОК добавлять спереди «/» к именам файлов в генерируемой инструкции #include (если она генерируется).
-q

Заставляет МОК добавлять спереди «/» к именам файлов в qt-файлах инструкции #include генерируемого кода.
-v Показывает версию МОК и Qt.

Можно принудительно указать МОК не проверять части заголовочного файла. Он распознает любые комментарии в стиле C++ (//), содержащие подстроки MOC_SKIP_BEGIN (начать пропуск) или MOC_SKIP_END (завершить пропуск). Они работают соответственно названию, и можно задавать их в несколько уровней. В конечном итоге с точки зрения МОК получится такой же результат, как если бы были удалены все строки между MOC_SKIP_BEGIN и MOC_SKIP_END.

Примеры использования

МОК почти всегда вызывается при помощи программы make, а не вручную. Обычно МОКу передается файл, содержащий объявления класса, как например:

class YourClass : public QObject < Q_OBJECT Q_PROPERTY( . ) Q_CLASSINFO( . ) public: YourClass( QObject * parent=0, const char * name=0 ); ~YourClass(); signals: public slots: >; 

Вот полезное правило сборки в make-файле (если используется GNU make):

m%.cpp: %.h moc $ < -o $@

Если требуется написать индивидуальные правила следующего вида:

mNAME.cpp: NAME.h moc $ < -o $@

Необходимо также не забывать добавлять mNAME.cpp в переменные в исходных файлах (заменяя соответствующими именами) и mNAME.o в переменные в объектных файлах. (Несмотря на то, что МОК не различает расширения файлов, что позволяет использовать .C, .cc, .CC, .cxx или даже .c++, все же "хорошим тоном" считается использование .cpp для наименования исходных файлов, написанных на языке C++). Если используется объявление класса в файлах C++, некоторые программисты используют правило make-файлов, наподобие этого:

NAME.o: mNAME.cpp mNAME.cpp: NAME.cpp moc -i $ < -o $@

Это гарантирует, что make вызовет МОК до компиляции NAME.cpp. Затем можно указать

#include "nNAME.cpp" 

в конце NAME.cpp, когда все классы, объявленные в этом файле, будут полностью определены.

Ошибки и диагностика

Иногда могут выдаваться ошибки линковки, сообщающие о том, что ВашКласс::имяКласса() неопределено или о том, что ВашКласс требует таблицу виртуальных методов. Эти ошибки наиболее часто встречаются когда забывают скомпилировать C++ код, сгенерированный МОК, или включить объектный файл в команду линковки. МОК также сообщает о некоторых опасных или неправильных конструкциях.

  • Приложения, использующие Qt
  • Инструменты разработки для Qt

Wikimedia Foundation . 2010 .

Using the Meta-Object Compiler (moc)

The Meta-Object Compiler, moc , is the program that handles Qt's C++ extensions.

The moc tool reads a C++ header file. If it finds one or more class declarations that contain the Q_OBJECT macro, it produces a C++ source file containing the meta-object code for those classes. Among other things, meta-object code is required for the signals and slots mechanism, the run-time type information, and the dynamic property system.

The C++ source file generated by moc must be compiled and linked with the implementation of the class.

Both qmake and CMake generate makefiles with build rules that will invoke moc accordingly, so you will not need to use the moc directly. qmake will add these build rules by default, whereas with CMake, you can use the AUTOMOC property to handle moc automatically. For more background information on moc , see Why Does Qt Use Moc for Signals and Slots?

Usage

moc is typically used with an input file containing class declarations like this:

class MyClass : public QObject < Q_OBJECT public: MyClass(QObject *parent = 0); ~MyClass(); signals: void mySignal(); public slots: void mySlot(); >;

In addition to the signals and slots shown above, moc also implements object properties as in the next example. The Q_PROPERTY() macro declares an object property, while Q_ENUM() declares a list of enumeration types within the class to be usable inside the property system.

In the following example, we declare a property of the enumeration type Priority that is also called priority and has a get function priority() and a set function setPriority() .

class MyClass : public QObject < Q_OBJECT Q_PROPERTY(Priority priority READ priority WRITE setPriority) public: enum Priority < High, Low, VeryHigh, VeryLow >; Q_ENUM(Priority) MyClass(QObject *parent = 0); ~MyClass(); void setPriority(Priority priority) < m_priority = priority; > Priority priority() const < return m_priority; > private: Priority m_priority; >;

The Q_FLAG() macro declares enums that are to be used as flags, i.e. OR'd together. Another macro, Q_CLASSINFO(), allows you to attach additional name/value pairs to the class's meta-object:

class MyClass : public QObject < Q_OBJECT Q_CLASSINFO("Author", "Oscar Peterson") Q_CLASSINFO("Status", "Active") public: MyClass(QObject *parent = 0); ~MyClass(); >;

The output produced by moc must be compiled and linked, just like the other C++ code in your program; otherwise, the build will fail in the final link phase. If you use qmake , this is done automatically. 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. Similarly, when setting AUTOMOC to ON , CMake will scan the header and source files at build time and invoke moc accordingly.

If the class declaration is found in the file myclass.h , the moc output should be put in a file called moc_myclass.cpp . This file should then be compiled as usual, resulting in an object file, e.g., moc_myclass.obj on Windows. This object should then be included in the list of object files that are linked together in the final building phase of the program.

Writing Make Rules for Invoking moc

For anything but the simplest test programs, it is recommended that you automate running the moc . By adding some rules to your program's makefile, make can take care of running moc when necessary and handling the moc output.

You can use CMake or qmake to generate makefiles that does all the necessary moc handling.

If you want to create your makefiles yourself, here are some tips on how to include moc handling.

For Q_OBJECT class declarations in header files, here is a useful makefile rule if you only use GNU make:

moc_%.cpp: %.h moc $(DEFINES) $(INCPATH) $ -o $@

If you want to write portably, you can use individual rules of the following form:

moc_foo.cpp: foo.h moc $(DEFINES) $(INCPATH) $ -o $@

You must also remember to add moc_foo.cpp to your SOURCES (substitute your favorite name) variable and moc_foo.o or moc_foo.obj to your OBJECTS variable.

Both examples assume that $(DEFINES) and $(INCPATH) expand to the define and include path options that are passed to the C++ compiler. These are required by moc to preprocess the source files.

While we prefer to name our C++ source files .cpp , you can use any other extension, such as .C , .cc , .CC , .cxx , and .c++ , if you prefer.

For Q_OBJECT class declarations in implementation ( .cpp ) files, we suggest a makefile rule like this:

foo.o: foo.moc foo.moc: foo.cpp moc $(DEFINES) $(INCPATH) -i $ -o $@

This guarantees that make will run the moc before it compiles foo.cpp . You can then put

#include "foo.moc"

at the end of foo.cpp , where all the classes declared in that file are fully known.

Command-Line Options

Here are the command-line options supported by the moc:

Option Description
-D[=] Define macro, with optional definition.
-E Preprocess only; do not generate meta-object code.
-f[] Force the generation of an #include statement in the output. This is the default for header files whose extension starts with H or h . This option is useful if you have header files that do not follow the standard naming conventions. The part is optional.
-Fdir macOS. Add the framework directory dir to the head of the list of directories to be searched for header files. These directories are interleaved with those specified by -I options and are scanned in a left-to-right order (see the manpage for gcc). Normally, use -F /Library/Frameworks/
-h Display the usage and the list of options.
-i Do not generate an #include statement in the output. This may be used to run the moc on a C++ file containing one or more class declarations. You should then #include the meta-object code in the .cpp file.
-I

Add dir to the include path for header files.
-M

Append additional meta data to plugins. If a class has Q_PLUGIN_METADATA specified, the key-value pair will be added to its meta data. This will end up in the Json object that gets resolved for the plugin at run time (accessible from QPluginLoader). This argument is typically used for tagging static plugins with information resolved by the build system.
-nw Do not generate any warnings. (Not recommended.)
-o

Write output to rather than to standard output.
-p

Makes the moc prepend / to the file name in the generated #include statement.
-U

Undefine macro.
@

Read additional command-line options from . Each line of the file is treated as a single option. Empty lines are ignored. Note that this option is not supported within the options file itself (i.e. an options file can't "include" another file).
-v Display moc 's version number.

You can explicitly tell the moc not to parse parts of a header file. moc defines the preprocessor symbol Q_MOC_RUN . Any code surrounded by

#ifndef Q_MOC_RUN ... #endif

is skipped by the moc .

Diagnostics

moc will warn you about a number of dangerous or illegal constructs in the Q_OBJECT class declarations.

If you get linkage errors in the final building phase of your program, saying that YourClass::className() is undefined or that YourClass lacks a vtable, something has been done wrong. Most often, you have forgotten to compile or #include the moc-generated C++ code, or (in the former case) include that object file in the link command. If you use qmake , try rerunning it to update your makefile. This should do the trick.

Build Systems

Including header moc files

qmake and CMake behave differently with regards to including header moc files.

To illustrate this with an example, suppose that you have two headers with corresponding source files: a.h , a.cpp , b.h , and b.cpp . Each header has a Q_OBJECT macro:

// a.h class A : public QObject < Q_OBJECT public: // . >;
// a.cpp #include "a.h" // . #include "moc_a.cpp"
// b.h class B : public QObject < Q_OBJECT public: // . >;
// b.cpp #include "b.h" // . #include "moc_b.cpp"

With qmake, if you don't include the moc-generated file ( moc_a.cpp / moc_b.cpp ), a.cpp , b.cpp , moc_a.cpp , and moc_b.cpp will be compiled separately. This can result in slower builds. If you include the moc generated files, only a.cpp and b.cpp will need to be compiled, as the moc generated code is included in those files.

With CMake, if you don't include the files, an single additional file is generated by moc (let's call it cmake.cpp for the sake of the example). cmake.cpp would include both moc_a.cpp and moc_b.cpp . Including the moc-generated file is still allowed with CMake, but it's not necessary.

For more information on CMake's moc support regarding this topic, see Including header moc files in sources.

Limitations

moc does not handle all of C++. The main problem is that class templates cannot have the Q_OBJECT macro. Here is an example:

class SomeTemplateint> : public QFrame < Q_OBJECT ... signals: void mySignal(int); >;

The following constructs are illegal. All of them have alternatives which we think are usually better, so removing these limitations is not a high priority for us.

Multiple Inheritance Requires QObject to Be First

If you are using multiple inheritance, moc assumes that the first inherited class is a subclass of QObject. Also, be sure that only the first inherited class is a QObject.

// correct class SomeClass : public QObject, public OtherClass < ... >;

Virtual inheritance with QObject is not supported.

Function Pointers Cannot Be Signal or Slot Parameters

In most cases where you would consider using function pointers as signal or slot parameters, we think inheritance is a better alternative. Here is an example of illegal syntax:

class SomeClass : public QObject < Q_OBJECT public slots: void apply(void (*apply)(List *, void *), char *); // WRONG >;

You can work around this restriction like this:

typedef void (*ApplyFunction)(List *, void *); class SomeClass : public QObject < Q_OBJECT public slots: void apply(ApplyFunction, char *); >;

It may sometimes be even better to replace the function pointer with inheritance and virtual functions.

Enums and Typedefs Must Be Fully Qualified for Signal and Slot Parameters

When checking the signatures of its arguments, QObject::connect() compares the data types literally. Thus, Alignment and Qt::Alignment are treated as two distinct types. To work around this limitation, make sure to fully qualify the data types when declaring signals and slots, and when establishing connections. For example:

class MyClass : public QObject < Q_OBJECT enum Error < ConnectionRefused, RemoteHostClosed, UnknownError >; signals: void stateChanged(MyClass::Error error); >;

Nested Classes Cannot Have Signals or Slots

Here's an example of the offending construct:

class A < public: class B < Q_OBJECT public slots: // WRONG void b(); >; >;

Signal/Slot return types cannot be references

Signals and slots can have return types, but signals or slots returning references will be treated as returning void.

Only Signals and Slots May Appear in the signals and slots Sections of a Class

moc will complain if you try to put other constructs in the signals or slots sections of a class than signals and slots.

© 2023 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *