Отвлечёмся от лирического вступления и перейдём к сути задачи:
есть описание некоторого графического интерфейса - более сложные графические интерфейсы (диалоги, формы) строятся из более простых - по кирпичику создаётся большой и сложный интерфейс.
Для пояснения приведу пример: адрес получателя представляет из себя следующую форму:
И данная форма может быть использована как в диалоге для отправления больших грузов, для заполнении информации о ком-то и т.п.
Главное, что это шаблонная форма адресата - и когда меняется этот шаблон везде в системе должен быть использован этот шаблон. При этом, возможность перекомпиляции не доступна - движок не знает и не должен знать какие внешние ресурсы что используют - все данные доступны только в run time.
Выражаясь в терминах spring framework - необходимо включать (include) одного файла в другой для повторного использования набора компонент.
В продолжении предыдущей статьи Quick start with loading extern ui рассмотрим включение одного ui-файла другим ui-файлом.
Стандартного способа я не нашёл, поэтому будем делать собственный компонент / custom widget, который будет загружать то, что ему скажут.
LoadableWidget.h:
#include <QWidget>
#include <QtDesigner/QDesignerExportWidget>
class QDESIGNER_WIDGET_EXPORT LoadableWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY(QString uiFilename READ getUiFilename WRITE setUiFilename)
public:
LoadableWidget(QWidget *parent = 0):QWidget(parent) {}
QString getUiFilename() const;
void setUiFilename(const QString fileName);
private:
QString uiFileName;
};
LoadableWidget.cpp:
#include <QDebug>
#include <QFile>
#include <QUiLoader>
#include <QWidget>
#include <QVBoxLayout>
#include "LoadableWidget.h"
QString LoadableWidget::getUiFilename() const
{
return this->uiFileName;
}
void LoadableWidget::setUiFilename(const QString fileName)
{
this->uiFileName = fileName;
QFile *file = new QFile(fileName);
if (file->exists())
{
QUiLoader *loader = new QUiLoader();
file->open(QFile::ReadOnly);
QWidget *widget = loader->load(file);
file->close();
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(widget);
}
else
{
qDebug() << "there is no file:" << fileName;
}
}
Пример использования данного компонента в ui-файле:
<ui version="4.0" >
<class>Form</class>
<widget class="QWidget" name="Form" >
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<!-- использование компонента, загружающего другие ui -->
<widget class="LoadableWidget" name="loadableWidget" >
<property name="uiFilename">
<string>../simple/widget.ui</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label" >
<property name="text" >
<string>simple.ui label</string>
</property>
</widget>
</item>
</layout>
</widget>
<!-- описание собственных компонент / custom widgets declaration -->
<customwidgets>
<customwidget>
<class>LoadableWidget</class>
<extends>QWidget</extends>
<header>loadablewidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
main.cpp приводить не буду - он такой же как и в предыдущей статье, точно такими же остаются шаги по созданию файла проекта (pro), Makefile'а и компиляции.
Обновлено: всё же я слукавил, что это всё - необходимо custom widget собрать и положить в отдельную библиотеку.
Для полного счастья надо собрать custom widget в библиотеку, и использовать её - Qt4: dynamic loading ui from an other ui, part 2
Комментариев нет:
Отправить комментарий