Глава 8
Генератор для Qt

8.1 Введение

В данной главе разсказывается о генераторе C++ файлов, необходимых при использовании библиотеки Qt http://www.trolltech.com. Описываемый генератор был протестирован на Qt версии 3.3.3.

При использовании Qt в трех случаях возникает необходимость генерирования C++ файлов с помощью входящих в состав Qt инструментов:

  1. Когда в заголовочном файле описывается класс, производный от QObject и в этом классе определены слоты и/или сигналы. В этом случае из заголовочного файла необходимо создать исходный файл, в котором будет находится реализация слотов и сигналов. Для генерации используется утилита moc. Обычно из файла a.h генерируется файл moc_a.cpp (т.е. расширение заменяется на .cpp, а к имени добавляется префикс moc_).
  2. Когда производный от QObject класс описывается в исходном файле. В этом случае должен быть создан дополнительный исходный файл, который подключается в основной исходный файл посредством директивы #include:


    1  ...
    2  class MyWidget : public QWidget { ... }
    3  
    4  #include "mywidget.moc"
    5  ...

    Для генерации используется утилита moc. Обычно из файла a.cpp генерируется файл a.moc (т.е. расширение заменяется на .moc).

  3. Из файла .ui, полученного с помощью Qt Designer, необходимо получить заголовочный и исходный файлы. Для генерации используется утилита uic. Из полученного заголовочного файла с помощью утилиты moc нужно так же получить еще один исходный файл с реализацией слотов и сигналов. Обычно из файла a.ui строятся файлы a.hpp, a.cpp, moc_a.cpp.

Генератор для Qt, который входит в состав Mxx_ru, позволяет обрабатывать перечисленные выше случаи.

8.2 Использование генератора для Qt

8.2.1 Подключение необходимых описаний к проектному файлу

Описание генератора для Qt содержится в файле mxx_ru/cpp/qt.rb, который подключается в проектный файл посредством require:


1  require ’mxx_ru/cpp/qt’
2  
3  Mxx_ru::setup_target( ... )

8.2.2 Создание генератора для Qt

Генератор для Qt реализован в виде класса Mxx_ru::Cpp::Qt_gen. Чтобы создать генератор для Qt необходимо создать в проекте объект этого класса:


1  require ’mxx_ru/cpp/qt’
2  
3  Mxx_ru::setup_target(
4   Mxx_ru::Cpp::Exe_target.new( "some/project/prj.rb" ) {
5   ...
6   qt = generator( Mxx_ru::Cpp::Qt_gen.new( self ) )
7   ...
8   }
9  )

Конструктор класса Qt_gen получает два аргумента: ссылку на объект-цель, в которой будет использован генератор, и набор символов препроцессора, которые будут установлены при компиляции проекта. По-умолчанию второй аргумент равен [’QT_DLL’, ’QT_THREAD_SUPPORT’]. Если используется вариант Qt в виде dll, с поддержкой многопоточности, то второй аргумент в конструктор Qt_gen можно не указывать. В остальных случаях следует передать во втором аргументе необходимые для используемой версии Qt символы препроцессора. Например, если необходим вариант Qt в виде статической библиотеки, но с поддержкой многопоточности, то следует указать:


1  require ’mxx_ru/cpp/qt’
2  
3  Mxx_ru::setup_target(
4   Mxx_ru::Cpp::Exe_target.new( "some/project/prj.rb" ) {
5   ...
6   qt = generator( Mxx_ru::Cpp::Qt_gen.new( self,
7   [ ’QT_THREAD_SUPPORT’ ] ) )
8   ...
9   }
10  )

8.2.3 Указание заголовочных файлов для генерации исходных файлов

Заголовочные файлы, из которых нужно сгенерировать исходные файлы посредством утилиты moc указываются генератору с помощью функции h2moc:


1  require ’mxx_ru/cpp/qt’
2  
3  Mxx_ru::setup_target(
4   Mxx_ru::Cpp::Exe_target.new( "some/project/prj.rb" ) {
5   ...
6   qt = generator( Mxx_ru::Cpp::Qt_gen.new( self ) )
7   ...
8   qt.h2moc( "mywidget.hpp" )
9   }
10  )

Указанное имя ищется относительно текущего значения sources_root (см.  5.10.1 на стр.  67). В приведенном пример файл mywidget.hpp должен быть расположен в каталоге some/project. В этот же каталог будет помещен результат работы утилиты moc1.

Из перечисленных с помощью метода h2moc файлов строятся файлы, в имя которого добавляется префикс moc_, а расширение заменяется на .cpp (если не изменено с помощью атрибута cpp_ext, см.  8.2.7 на стр.  95). Так из some/project/mywidget.hpp будет получен файл some/project/moc_mywidget.cpp.

8.2.4 Указание исходных файлов для генерации исходных файлов

Исходные (.cpp) файлы, из которых нужно сгенерировать исходные (.moc) файлы посредством утилиты moc указываются генератору с помощью функции cpp2moc:


1  require ’mxx_ru/cpp/qt’
2  
3  Mxx_ru::setup_target(
4   Mxx_ru::Cpp::Exe_target.new( "some/project/prj.rb" ) {
5   ...
6   qt = generator( Mxx_ru::Cpp::Qt_gen.new( self ) )
7   ...
8   qt.cpp2moc( "mywidget.cpp" )
9   }
10  )

Указанное имя ищется относительно текущего значения sources_root (см.  5.10.1 на стр.  67). В приведенном пример файл mywidget.cpp должен быть расположен в каталоге some/project. В этот же каталог будет помещен результат работы утилиты moc2.

Из перечисленных с помощью метода cpp2moc файлов строятся файлы, у которых расширение заменяется на .moc (если не изменено с помощью атрибута moc_ext, см.  8.2.9 на стр.  96). Так из some/project/mywidget.cpp будет получен файл some/project/mywidget.moc.

8.2.5 Указание .ui-файлов

Результаты работы Qt Designer, сохраненные в виде .ui-файлов, указываются генератору с помощью метода ui:


1  require ’mxx_ru/cpp/qt’
2  
3  Mxx_ru::setup_target(
4   Mxx_ru::Cpp::Exe_target.new( "some/project/prj.rb" ) {
5   ...
6   qt = generator( Mxx_ru::Cpp::Qt_gen.new( self ) )
7   ...
8   qt.ui( "myform.ui" )
9   }
10  )

Указанное имя ищется относительно текущего значения sources_root (см.  5.10.1 на стр.  67). В приведенном пример файл myform.ui должен быть расположен в каталоге some/project. В этот же каталог будет помещен результат работы утилиты ui.

Из перечисленных с помощью метода ui файлов строятся файлы заголовочные файлы, у которых расширение заменяется на .hpp (если не изменено с помощью атрибута hpp_ext, см.  8.2.8 на стр.  95), и исходные файлы, у которых расширение заменяется на .cpp (если не изменено с помощью атрибута cpp_ext, см.  8.2.7 на стр.  95). Имена сгенерированных заголовочных файлов затем указываются генератору через метод h2moc для генерации вспомогательного исходного файла. В результате из some/project/myform.ui будут получены файлы some/project/myform.hpp, some/project/myform.cpp, some/project/moc_myform.cpp.

8.2.6 Расположение результатов работы утилиты moc

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

В классе Mxx_ru::Cpp::Qt_gen есть атрибут moc_result_subdir, который определяет размещение разультатов работы moc. Если этот атрибут содержит nil (значение по-умолчанию), то сгенерированные файлы помещаются рядом с исходными файлами. Если назначить атрибуту moc_result_subdir значение, то в качестве результирующего будет использоваться указанный подкаталог исходного каталога. Например:


1  qt = generator( Mxx_ru::Cpp::Qt_gen.new( self ) )
2  qt.moc_result_subdir = "moc"
3  qt.h2moc( "h/mywidget.hpp" )

Из файла h/mywidget.hpp будет сгенерирован файл h/moc/moc_mywidget.cpp.

Значение атрибута moc_result_subdir оказывает влияние только на файлы, которые перечисляются с помощью методов h2moc и cpp2moc.

8.2.7 Изменение расширения для сгенерированных исходных файлов

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


1  qt = generator( Mxx_ru::Cpp::Qt_gen.new( self ) )
2  qt.cpp_ext = ".CC";
3  qt.h2moc( "h/mywidget.H" )

Из файла h/mywidget.H будет сгенерирован файл h/mywidget.CC.

8.2.8 Изменение расширения для сгенерированных заголовочных файлов

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


1  qt = generator( Mxx_ru::Cpp::Qt_gen.new( self ) )
2  qt.hpp_ext = ".h";
3  qt.ui( "myform.ui" )

Из файла myform.ui будет сгенерирован файл myform.h.

8.2.9 Изменение расширения для сгенерированных moc-файлов

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


1  qt = generator( Mxx_ru::Cpp::Qt_gen.new( self ) )
2  qt.moc_ext = ".cpp.moc";
3  qt.cpp2moc( "mywidget.cpp" )

Из файла mywidget.cpp будет сгенерирован файл mywidget.cpp.moc.

8.2.10 Изменение имени утилиты moc

Имя утилиты moc находится в атрибуте moc_name объекта-генератора. По-умолчанию это moc. Изменение данного атрибута позволяет указать другое имя, которое будет использоваться для запуска утилиты moc:


1  qt = generator( Mxx_ru::Cpp::Qt_gen.new( self ) )
2  qt.moc_name = "/usr/src/qt.4.0.b2/bin/moc"

8.2.11 Изменение имени утилиты uic

Имя утилиты uic находится в атрибуте uic_name объекта-генератора. По-умолчанию это uic. Изменение данного атрибута позволяет указать другое имя, которое будет использоваться для запуска утилиты uic:


1  qt = generator( Mxx_ru::Cpp::Qt_gen.new( self ) )
2  qt.uic_name = "/usr/src/qt.4.0.b2/bin/uic"

Hosted by uCoz