Russian Qt Forum
Ноябрь 22, 2024, 04:41 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Десериализация UI  (Прочитано 6176 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Декабрь 23, 2020, 08:29 »

Добрый день

Очень старый код который однако поддерживать обязан. Базовый класс (псевдокод)
Код
C++ (Qt)
class BaseControl {
 BaseControl( void );
 void Init( Window * win, const std::string & txt ... );
 ...
 virtual const std::string & SerialName( void ) const;
 ...
 virtual void Read ( Stream & stream );
 virtual void Write( Stream & stream );
};
 
Ну и плюс фабрика (с темплейтпми) и макруха регистрации в ней. Работает так:
читается имя из потока, по нему фабрика делает new нужного типа и зовется виртуальный Read, который зовет конкретный Init

Однако дефаулт конструктор оказался очень неудобным (при переводе на Qt) , и я решил вместо Init иметь нормальные конструкторы во всех классах наследниках (десятка 2). Конечно развалилась хвабрика чтения. Нужно ли ее "домучивать"? Или лучше сбацать в духе "современного С++", там function, bind и все такое? Тогда как?

Спасибо
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #1 : Декабрь 23, 2020, 10:17 »

Однако дефаулт конструктор оказался очень неудобным (при переводе на Qt) , и я решил вместо Init иметь нормальные конструкторы во всех классах наследниках (десятка 2). Конечно развалилась хвабрика чтения. Нужно ли ее "домучивать"? Или лучше сбацать в духе "современного С++", там function, bind и все такое? Тогда как?

Почему фабрика развалилась?
В фабрике нельзя просто заменить make() на make( QWidget * parent, Qt::WindowFlags ) или что там используется?

Можно вообще сделать отдельно Qt Widgets и оставить эту сериализацию.

Код
C++ (Qt)
 
class MyWidget : public QWidget
{
public:
   MyWidget ( QWidget * parent, Qt::WindowFlags );
};
 
 

Код
C++ (Qt)
class BaseControlSerializer
{
 BaseControlSerializer( void );
 virtual void Init( QWidget * win, const std::string & txt ... ) = 0;
 ...
 virtual const std::string & SerialName( void ) const;
 ...
 virtual void Read ( Stream & stream ) = 0;
 virtual void Write( Stream & stream ) = 0;
 
 virtual QWidget * widget () = 0;
};
 
template < typename _Widget >
class GenericControlSerializer : public BaseControlSerializer
{
 _Widget * m_widget;
 
private:
 GenericControlSerializer ( void );
 virtual void Init( QWidget * win, const std::string & txt ... ) override;
 ...
 virtual void Read ( Stream & stream ) override;
 virtual void Write( Stream & stream ) override;
 
 virtual QWidget * widget () override { return m_widget; };
};
 
 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Декабрь 23, 2020, 11:19 »

Почему фабрика развалилась?
В фабрике нельзя просто заменить make() на make( QWidget * parent, Qt::WindowFlags ) или что там используется?
Можно, просто интересно "попробывать" новое  Улыбающийся

Конкретный контрол выглядит так
Код
C++ (Qt)
class MyControl : public QWidget, public BaseControl {
..
};
Или так
Код
C++ (Qt)
class MyStaticText : public QLabel, public BaseControl {
..
};

Пока наметил так
Код
C++ (Qt)
class BaseControl {
..
static BaseControl * Read( Stream & stream );
..
};
И покидать эти статики в мапу. Но может как-то по другому (в свете новых фич языка и.т.п.) ?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Декабрь 25, 2020, 08:50 »

Пока наметил так
Так не катит Улыбающийся Собсно десериализация - это "тривиально" (здесь это слово подходит). Сначала создаем объект конструктором и потом читаем из потока, объект всегда валиден. Но в данном случае я не могу безболезненно создать объект (см примеры классов выше). Сделал так
Код
C++ (Qt)
static MyControl * CreateForRead( Window * win )
{
 return new MyControl(win, QRect(0, 0, 256, 100), "Dummy");
}
Для всех 25 контролов. Правда здесь окно имеется. Интересно а что если бы его не было? Тогда не вижу хорошего решения
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #4 : Декабрь 25, 2020, 13:43 »

Так не катит Улыбающийся Собсно десериализация - это "тривиально" (здесь это слово подходит). Сначала создаем объект конструктором и потом читаем из потока, объект всегда валиден. Но в данном случае я не могу безболезненно создать объект (см примеры классов выше). Сделал так

Поэтому я и предложил отделить сериализацию от объекта.
Фабрика может создавать не сам Control, а ControlSerializator, который в свою очередь вычитывает из stream необходимые параметры и, если все ОК, создает Control.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.162 секунд. Запросов: 23.