Варианты программы

Я выполняю некоторые алгоритмические работы с использованием C++. У моих алгоритмов есть некоторые опции, которые мне нужно добавить в мою программу с минимальными усилиями. В настоящее время я использую этот код.

Все работает так, как ожидалось: я добавил код в свою программу, поэтому я могу вызывать двоичный код с такими аргументами, как -oopt1=val1,opt2=val2 и параметры устанавливаются автоматически.

Проблема в том, что я также пишу графический интерфейс одновременно. Теперь каждый параметр должен быть установлен/запрошен с использованием графического интерфейса. Однако мне может понадобиться spinbox для целочисленного значения и флажок для логической опции. Я использую Qt в качестве инструментария, поэтому я мог просто написать функцию-член, которая возвращает QWidget* который является подходящим базовым классом.

Однако я не хочу использовать какой-либо GUI-код в заголовке, где я объявляю свои параметры, так как я хотел бы отделить графический интерфейс от остальной части программы. Я мог бы подклассировать любой параметр для создания соответствующего QWidget*, но если я получу список OptBase*, я не знаю, какой виджетом я должен создать.

Есть ли способ, которым я могу сохранить графический интерфейс отдельно от остальной части программы, все еще имея возможность создавать соответствующие виджеты?

2 ответа

Для меня решение - создать абстрактный завод: фабрика должна иметь интерфейс с двумя абстрактными методами для созданияBoolOption и CreateChoiceOption. Возможно, потребуется больше методов. Затем вы можете сделать две конкретные реализации этого интерфейса, где один возвращает те же, что и сейчас, но когда вы работаете в QT, вы можете использовать другую реализацию, которая возвращает производный класс optbase, который знает как создать виджет. Вы даже можете использовать множественное наследование (т.е. второй интерфейс), так что вам не нужно создавать метод в первом интерфейсе, чтобы специально создать виджет. Конечно, при запуске приложения QT вы должны явно передать второй интерфейс, если хотите создать виджет. Сама абстрактная фабрика должна быть передана строителю альгобазы. Т.е. зависимость.

class ifactory{
public:
 virtual Option<bool>* createBoolOption()=0;
 virtual ChoiceOption<mode>* createChoiceOption()=0;
 virtual Widget* createWidget()=0; //here or in another interface
};

class ConcreteNonGuiFactory : public ifactory{
 virtual Option<bool>* createBoolOption();
 virtual ChoiceOption<mode>* createChoiceOption();
 virtual Widget* createWidget()={;}; 
};

class ConcreteGuiFactory : public ifactory{
 virtual Option<bool>* createBoolOption();
 virtual ChoiceOption<mode>* createChoiceOption();
 virtual Widget* createWidget(); 
}; 

class Algo1 : public AlgoBase{
public:
 Algo1(ifactory& f):factory(f){
 ChoiceOption<mode>* opt = factory.createChoiceOption();
 }
private:
 ifactory factory;
}
</mode></mode></bool></mode></bool></mode></bool>

Если создание виджета в другом интерфейсе, вы можете уменьшить свои зависимости. В этом примере, по крайней мере, виджет должен быть объявлен вперед.


Вам нужна куча переменных, к которым можно получить доступ как с помощью setter (GUI, парсинг-парса), так и с помощью getter (функция алгоритма). QVariant должно быть хорошо. Поскольку у вас есть имена, они также имеют неявные типы. Getter должен получить значение по их имени и явно преобразовать тип. Сеттер не должен заботиться - QVariant будет.

Создайте экземпляр singleton, который имеет карту имен опций. Реализовать слоты, вызванные сигналами изменения значения GUI, задавать значения на карте. например:

class VarTable
{
 static VarTable & instance(){ static VarTable inst; return inst; }
 QMap<qstring, qvariant=""> _map;
public: 
 void setVar( QString n, QVariant v ){ _map[n] = v };
 QVariant getVar( QString n ) const { return _map[n]; }
};

//Call in Slot triggered by a value-change signal (e.g. QEditLine::returnPressed)
VarTable::instance().setVal( "option1", val1 );

//Regrieve in non-gui code
QString option1 = VarTable::instance().getVal( "option1" ).toString();
</qstring,>

С уважением

PS: Я не скомпилировал код, у меня есть опечатки.

licensed under cc by-sa 3.0 with attribution.