[Предыдущая: Портирование на Qt 4 - Перетаскивание (Drag and Drop)] [Содержание] [Следующая: Переход на Графическое представление]
Портирование файлов UI в Qt 4
Qt Designer значительно изменился в выпуске Qt 4. Мы изменили точку зрения о Qt Designer как об IDE и сосредоточились на создании надёжного построителя форм, который может быть расширен и встроен в существующие IDE. Наши усилия не прекращаются и включают Visual Studio Integration, а также интеграцию Designer с KDevelop и возможно другими IDE.
Наиболее важные изменения в Qt Designer 4, которые оказывают воздействие на UI-файлы, подытожены ниже:
- Убран менеджер проектов. Qt Designer теперь только читает и редактирует UI-файлы. Нет понятия файла проекта (.pro).
- Убран редактор кода. Qt Designer больше не может быть использован для редактирования файлов исходных текстов.
- Изменён формат UI-файлов. Qt Designer 4 не может прочитать файлы, созданные Qt Designer 3 и более ранними версиями. Тем не менее, мы предоставили инструмент uic3 для генерации кода Qt 4 из UI-файлов Qt 3, а также для конвертирования старых UI-файлов в формат, который может читать Qt Designer 4.
- Изменена структура кода, генерируемого uic. Файл myform.ui, содержащий форму MyForm, теперь конвертируется в один заголовочный файл ui_myform.h, который содержит объявление и inline-определение POD класса Ui::MyForm.
- Новая файловая система ресурсов. Данные пиктограмм более не сохраняются в UI-файле. Вместо этого пиктограммы помещаются в файлы ресурсов (.qrc).
Остальная часть этого документа объясняет, как рассматривать основные отличия между Qt Designer 3 и Qt Designer 4:
Для получения дополнительной информации о портировании с Qt 3 на Qt 4 смотрите Портирование на Qt 4 и qt3to4 - Инструмент портирования с Qt 3 на Qt 4. Смотрите также Руководство по Qt Designer.
Вывод uic
В Qt 3 uic генерирует заголовочный файл и реализацию класса, которые унаследованы от одного из виджетов Qt. Чтобы использовать форму, программист включает сгенерированные исходные коды в приложение и создаёт экземпляр класса.
В Qt 4 uic создаёт заголовочный файл, содержащий POD класса. Имя этого класса - имя объекта главного контейнера, уточнённого с пространством имён Ui (например, Ui::MyForm). Класс, реализованный с использованием inline-функции, устраняет необходимость в отдельном файле .cpp. Как и в Qt 3 этот класс содержит указатели на все виджеты внутри формы как открытые члены. Кроме того, сгенерированный класс предоставляет открытый метод setupUi().
Класс, сгенерированный uic, не является QWidget; фактически, это даже не QObject. Взамен, это класс, который знает как заполнить экземпляр главного контейнера с содержимым формы. Программист создаёт сам главный контейнер, затем передаёт его setupUi().
Например, здесь вывод uic для простой формы helloworld.ui (некоторые детали были удалены для простоты):
namespace Ui {
class HelloWorld
{
public:
QVBoxLayout *vboxLayout;
QPushButton *pushButton;
void setupUi(QWidget *HelloWorld)
{
HelloWorld->setObjectName(QString::fromUtf8("HelloWorld"));
vboxLayout = new QVBoxLayout(HelloWorld);
vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
pushButton = new QPushButton(HelloWorld);
pushButton->setObjectName(QString::fromUtf8("pushButton"));
vboxLayout->addWidget(pushButton);
retranslateUi(HelloWorld);
}
};
}
В этом случае, главным контейнером был задан QWidget (или любой подкласс QWidget). Мы начали с шаблона QMainWindow в Qt Designer, тип параметра setupUi()'а будет QMainWindow.
Имеется два способа создания экземпляра нашей формы. Один подход - создать экземпляр класса Ui::HelloWorld, экземпляр главного контейнера (простой QWidget) и вызвать setupUi():
#include <QApplication>
#include <QWidget>
#include "ui_helloworld.h" // определяет Ui::HelloWorld
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget w;
Ui::HelloWorld ui;
ui.setupUi(&w);
w.show();
return app.exec();
}
Второй подход - унаследовать и от класса Ui::HelloWorld и от главного контейнера, а также вызвать setupUi() в конструкторе подкласса. В этом случае, QWidget (или один из его подклассов, например, QDialog) должен появиться сначала в списке базовых классов, поэтому moc примет его правильно. Например:
#include <QApplication>
#include <QWidget>
#include "ui_helloworld.h" // определяет Ui::HelloWorld
class HelloWorldWidget : public QWidget, public Ui::HelloWorld
{
Q_OBJECT
public:
HelloWorldWidget(QWidget *parent = 0)
: QWidget(parent)
{ setupUi(this); }
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
HelloWorldWidget w;
w.show();
return app.exec();
}
Этот второй метод полезен при портировании форм Qt 3 на Qt 4. HelloWorldWidget - класс, чей экземпляр является действительной формой и который содержит открытые указатели на все виджеты. По этой причине он имеет интерфейс, идентичный имеющемуся в классе, сгенерированном uic в Qt 3.
Создание классов POD из UI-файлов - более гибкий и общий способ, чем старый подход создания виджетов. Qt Designer не нужно знать что-либо о главном контейнере отдельно от базового класса виджета, от которого он унаследован. Действительно, Ui::HelloWorld может использоваться для заполнения любого контейнера, который унаследован от QWidget. И наоборот, все не имеющие отношения к ГПИ аспекты главного контейнера могут быть реализованы программистом в исходных кодах приложения без ссылки на форму.
Работа с uic3
Вместе с Qt 4 идёт инструмент uic3 для работы со старыми .ui-файлами. Его можно использовать двумя способами:
- Для генерации заголовков и исходных кодов для виджета, чтобы реализовать любые пользовательские сигналы и слоты добавленные используя Qt Designer 3.
- Для генерации нового UI-файла, который может быть использован с Qt Designer 4.
Вы можете использовать оба эти метода в сочетании для получения UI, заголовочных файлов и файлов исходного кода, которые вы можете использовать в качестве отправной точки при портировании вашего пользовательского интерфейса на Qt 4.
Первый метод генерирует заголовок в стиле Qt 3 и реализацию, которая использует виджеты Qt 4 (это включает классы совместимости с Qt 3 в библиотеке Qt3Support). Этот процесс легко узнаваем для всех, использующих для работы Qt Designer 3:
uic3 myform.ui > myform.h
uic3 -impl myform.h myform.ui > myform.cpp
Получившиеся файлы myform.h и myform.cpp реализуют форму в Qt 4, используя QWidget, который включает в себя пользовательские сигналы, слоты и соединения, заданные в UI-файле. Тем не менее, ниже смотрите ограничения этого метода.
Второй метод - использовать uic3 для конвертации .ui-файла Qt Designer 3 в формат Qt Designer 4:
uic3 -convert myform3.ui > myform4.ui
Получившийся файл myform4.ui можно редактировать в Qt Designer 4. Заголовочный файл для формы генерируется uic Qt 4. Смотрите главу Использование UI-файла в вашем приложении Руководства по Qt Designer для информации о предпочтительных способах использования форм, созданных с помощью Qt Designer 4.
uic3 старается отобразить классы Qt 3 и их свойства на Qt 4. Однако, в Qt 4 поведение некоторых классов значительно изменилось. Чтобы сохранить форму работающей, некоторые классы Qt 3 отображаются на классы в библиотеке Qt3Support. Таблица 1 показывает список классов, на которые это распространяется.
Ограничения uic3
Конвертирование UI-файлов Qt 3 на Qt 4 имеет некоторые ограничения. Большинство достойных внимания ограничений фактически заключаются в том, что так как uic больше не генерирует QObject, то невозможно определить пользовательские сигналы или слоты для формы. Вместо этого программист должен определить эти сигналы и слоты в главном контейнере и соединить их с виджетами на форме после вызова setupUi(). Например:
class HelloWorldWidget : public QWidget, public Ui::HelloWorld
{
Q_OBJECT
public:
HelloWorldWidget(QWidget *parent = 0);
public slots:
void mySlot();
};
HelloWorldWidget::HelloWorldWidget(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
QObject::connect(pushButton, SIGNAL(clicked()),
this, SLOT(mySlot()));
}
void HelloWorldWidget::mySlot()
{
...
}
Небрежный способ портирования форм, содержащих пользовательские сигналы и слоты, - генерация кода используя uic3, а не uic. Так как uic3 генерирует QWidget, он заполняет его пользовательским сигналам, слотам и соединениями, указанными в UI-файле. Однако uic3 может генерировать только код из UI-файлов Qt 3, которые подразумевают что UI-файлы никогда не получают перевод и нужно редактировать используя Qt Designer 3.
Обратите также внимание на то, что можно создать скрытые соединения между виджетами в форме и главном контейнере. После заполнения setupUi() главного контейнера с дочерними виджетами она просматривает список слотов главного контейнера в поисках имён вида on_objectName_signalName().
Если форма содержит виджет, чьё имя объекта - objectName, и если этот виджет имеет сигнал с именем signalName, тогда этот сигнал будет соединён со слотом главного контейнера. Например:
class HelloWorldWidget : public QWidget, public Ui::HelloWorld
{
Q_OBJECT
public:
HelloWorldWidget(QWidget *parent = 0);
public slots:
void on_pushButton_clicked();
};
HelloWorldWidget::HelloWorldWidget(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
}
void HelloWorldWidget::on_pushButton_clicked()
{
...
}
Из-за соглашения об именовании setupUi() автоматически соединяет сигнал pushButton'а, clicked(), со слотом HelloWorldWidget'а, on_pushButton_clicked().
Пиктограммы
В Qt 3 двоичные данные для пиктограмм, использованных в форме, сохраняются в UI-файл. В Qt 4 пиктограммы и любые другие внешние файлы могут быть скомпилированы в приложение путем перечисления их в файле ресурсов (.qrc). Этот файл преобразовывается в файл исходных кодов C++ используя компилятор ресурсов Qt (rcc). После этого данные в файлах доступны для любого класса Qt, который получает аргумент с именем файла.
Представьте себе, что у нас есть две пиктограммы, yes.png и no.png. Мы создаём файл ресурсов с именем icons.qrc со следующим содержимым:
<RCC version="1.0">
<qresource prefix="/icons">
<file>yes.png</file>
<file>no.png</file>
</qresource>
</RCC>
Далее, мы добавляем файл ресурса в наш .pro-файл:
RESOURCES += icons.qrc
Когда запущен qmake, он создаст соответствующие правила Make-файла для вызова rcc с файлом ресурсов, и компилирует и линкует результат в приложение. Доступ к пиктограммам можно получить как изложено ниже:
QFile file(":/icons/yes.png");
QIcon icon(":/icons/no.png");
QPixmap pixmap(":/icons/no.png");
В каждом подобном случае, ведущее двоеточие сообщает Qt искать файл в виртуальном дереве файлов, описанном набором файлов ресурсов, скомпилированных в приложение вместо файловой системы.
В файле .qrc, атрибут тега qresource, prefix, используется для размещения файлов по категориям и установки виртуального пути, по которому будут доступны файлы.
Предупреждение: Если файл ресурса не был слинкован непосредственно в приложение, а вместо этого в динамическую или статическую библиотеку, которая позднее линкуется с приложением, его виртуальное дерево файлов не будет доступно для QFile и его друзей, пока не вызван макрос Q_INIT_RESOURCE(). Этот макрос принимает один аргумент, которым является имя файла .qrc, без пути или расширения файла. Удобным местом для инициализации ресурсов является верхняя часть функции main() приложения.
В Qt Designer 4 мы можем связать любое количество файлов ресурсов с формой, используя инструмент редактора ресурсов. Виджеты в форме могут получить доступ ко всем пиктограммам, указанным в соответствующих файлах ресурсов.
Вкратце, портирование пиктограмм из Qt 3 на форму Qt 4 приводит к следующим шагам:
- Используйте uic3 -convert чтобы получить UI-файл, понятный Qt Designer 4.
- Создайте файл .qrc со списком всех файлов пиктограмм.
- Добавьте файл ресурса в .pro файл.
- Откройте форму в Qt Designer 4 и добавьте файл ресурсов в редактор ресурсов формы.
- Установите свойства пиктограмм для соответствующих виджетов.
Пользовательские виджеты
Qt Designer 3 поддерживает определение пользовательских виджетов указанием их имён, заголовочного файла и методов. В Qt Designer 4 пользовательский виджет всегда создаётся "продвигая" существующий виджет Qt в пользовательский класс. Qt Designer 4 принимает, что пользовательский виджет будет унаследован от виджета, который был продвинут. В редакторе форм, пользовательский виджет будет помнить внешний вид, поведение, свойства, сигналы и слоты базового виджета. В настоящее время невозможно сообщить Qt Designer 4 о том, что пользовательский виджет будет иметь дополнительные сигналы и слоты.
uic3 -convert обрабатывает преобразование пользовательских виджетов в новый формат .ui, тем не менее все пользовательские сигналы и слоты будут потеряны. Кроме того, так как Qt Designer 3 никогда не знает о базовом классе пользовательского виджета, он берёт QWidget. Этого часто достаточно. Если нет, пользовательские виджеты вставляются в форму вручную.
Подключаемые модули пользовательских виджетов, которые содержат пользовательские виджеты, используемые в Qt Designer, сами должны быть портированы перед тем, как они могут быть использованы в формах, портированных с помощью uic3. Документ Портирование на Qt 4 содержит информацию об основных проблемах портирования, которые могут быть применены к коду самого пользовательского виджета, а глава Создание пользовательских виджетов для Qt Designer Руководства по Qt Designer описывает как можно собрать портированный виджет, чтобы он работал в Qt Designer 4.
[Предыдущая: Портирование на Qt 4 - Перетаскивание (Drag and Drop)] [Содержание] [Следующая: Переход на Графическое представление]
Авторские права © 2010 Nokia Corporation и/или её дочерние компании |
Торговые марки |
Qt 4.6.4 |
|