我正在使用C ++进行一些算法工作。我的算法有一些选项,我需要尽可能少的努力添加到我的程序。我目前正在使用this代码。
一切都按预期工作:我在程序中添加了一些代码,因此我可以使用-oopt1=val1,opt2=val2
等参数调用二进制文件,并自动设置选项。
问题是我也在同时编写GUI。现在,必须能够使用GUI设置/请求每种选项。但是,我可能需要一个整数值的旋转框和一个布尔选项的复选框。我使用Qt作为工具包,所以我可以写一个成员
返回QWidget*
的函数,它是适当的基类。
但是,我不希望在我声明我的选项的标题中有任何特定于GUI的代码,因为我想将GUI与程序的其余部分分开。我可以将任何Option子类化为创建适当的QWidget*
,但如果我得到OptBase*
的列表,我就不知道应该创建哪种小部件。
是否有某些方法可以让GUI与程序的其余部分分开,同时仍然能够创建适当的小部件?
答案 0 :(得分:2)
对我来说,解决方案是创建一个抽象工厂: 工厂应该有一个带有两个抽象方法的接口来创建BoolOption和CreateChoiceOption。可能需要更多方法 然后,您可以创建此接口的两个具体实现,其中一个返回与您现在正在执行的相同的实现,但是当您在QT中运行时,您可以使用另一个实现,该实现返回一个知道如何创建窗口小部件的optbase派生类。 您甚至可以使用多重继承(即第二个接口),这样您就不必在第一个界面中创建方法来专门创建窗口小部件。 当然,在运行QT应用程序时,如果要创建窗口小部件,则必须明确地转换为第二个接口。 抽象工厂本身应该传递给algobase的构造函数。即依赖注入。
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;
}
如果窗口小部件的创建位于不同的界面中,则可以减少依赖关系。 在此示例中,至少必须向前声明窗口小部件。
答案 1 :(得分:1)
您需要通过setter(GUI,commang-line解析器)和getter(算法函数)访问一堆变量。 QVariant应该没问题。由于您的选项具有名称,因此它们也具有隐式类型。 Getter应该按名称检索值并显式进行类型转换。 Setter不应该关心 - QVariant会。
创建一个包含选项名称映射的单例实例。实现由GUI值更改信号触发的插槽,在map中设置值。 e.g:
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();
此致
P.S。:我没有编译代码,但是有一些错别字。