Russian Qt Forum

Qt => Кладовая готовых решений => Тема начата: _OLEGator_ от Март 30, 2013, 16:42



Название: "Аналог" Prism на Qt
Отправлено: _OLEGator_ от Март 30, 2013, 16:42
Данный компонент предоставляет возможность создавать приложение с "слабосвязанным" интефейсом и ядром.

В частности, такое уже реализовано для .Net платформы и носит название Prism (рус. Призма) - статья на эту тему (http://msdn.microsoft.com/ru-ru/magazine/cc785479.aspx).

Так вот, после продолжительной работы с Prism, появилось желание создать некий аналог для Qt.
В силу менее гибкой объектной модели языка и ограничений C++, конечно что-то сделать вообще не удастся.

На данный момент удалось реализовать следующее:
- Возможность задавать объекту источник данных, для детей - связь между свойством источника данных и свойством этого объекта.
  Соответственно, все изменения автоматически отслеживаются (источника данных, свойства) и обрабатываются. Обрабатывается также удаление объекта-источника данных.
- Реализована событийная машина, позволяющая подписываться на определенное событие с указанием функции (слота), который будет вызван, при совпадении аргументов.
  События регистрируются как текстовые строки, у которых может быть до 3х произвольных аргументов. Это реализовано на шаблонных функциях.
  Важно отметить, что одно событие может вызываться с любыми аргументами и их количеством (от 0 до 3) и будет вызван только тот слот, у которого полностью совпадут типы аргументов.
  Также не удастся подписаться на событие с совместимыми аргументами, типа QString с char*. Необходимо полное их совпадение.

Все это реализовано на основе механизмов объектной модели и сигналов/слотов, поэтому есть определенные ограничения по скорости работы и количеству операций в секунду, а также потребует наследование от QObject.

Пример связывания класса и интерфейса, для его редактирования:
Код
C++ (Qt)
class CXData: public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QString surname READ surname WRITE setSurname NOTIFY surnameChanged)
 
public:
CXData(const QString& aName, const QString& aSurname);
~CXData();
 
public slots:
QString name();
QString surname();
 
void setName(const QString& aName);
void setSurname(const QString& aSurname);
 
signals:
void nameChanged(const QString& aName);
void surnameChanged(const QString& aSurname);
 
private:
QString mName;
QString mSurname;
};
 
Q_DECLARE_METATYPE(CXData*);
 
...
 
QWidget* widget = new QWidget();
QLineEdit* nameEdit = new QLineEdit(widget);
QLineEdit* surnameEdit = new QLineEdit(widget);
CXData* data = new CXData( ... );
...
SetDataSource(widget, data);
BindValue("name", nameEdit, "text", E_TwoWay);
BindValue("surname", surnameEdit, "text", E_TwoWay);
//Пример подписки на событие
CXEventMachine::subscribe(this, PRISM_EVENT(SelectData), PRISM_METHOD(setSelectData()));
//Пример генерации события с параметрами
CXEventMachine::postEvent(PRISM_EVENT(SelectData), 100);

Библиотека и тестовый проект во вложении (собран на 4.8.2, MSVS 2010).