2013-06-25 89 views
0

我在做一些使用C++的算法工作。我的算法有一些选项,我需要尽可能少地加入到我的程序中。我目前使用this的代码。程序选项

一切正常:我添加了一些代码,我的计划,所以我可以调用带参数的二进制像-oopt1=val1,opt2=val2和选项会自动设置。

的问题是,我也写在同一时间的GUI。现在,每种选项都必须能够使用GUI设置/请求。但是,我可能需要一个整数值的spinbox和一个布尔选项的复选框。我正在使用Qt作为工具包,所以我可以写一个成员 函数返回QWidget*这是适当的基类。

不过,我不希望在我宣布我的选择,因为我想在GUI从程序的其余部分分开的头任何特定的GUI代码。我可以创建一个合适的QWidget*的子类,但是如果我得到一个OptBase*的列表,我不知道应该创建什么样的小部件。

是否有某种方式,我可以保持距离,同时仍然能够创造适当的小部件程序的其余部分分开的GUI?

+1

什么[的QVariant](http://qt-project.org/doc/qt-5.0/qtcore/qvariant.html)或[Boost.Variant](http://www.boost.org/doc/ libs/1_53_0/doc/html/variant.html)? – Trompa

回答

2

对我来说,解决方案是创建一个抽象工厂: 工厂应该有一个接口,其中有两个抽象方法createBoolOption和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; 
} 

如果小部件的创建处于不同的界面中,则可以减少依赖关系。 在这个例子中,至少该小部件必须进行前向声明。

+0

+ 1像这样的答案,再次向这位用户购买 –

+0

好主意,但我有以下问题:我有很多自定义枚举,所以我想要一个模板函数来创建ChoiceOption 。他们也有相同的小部件代表他们,但问题是虚拟功能不允许被模板化... – hfhc2

1

你需要一组变量由两个二传手(GUI,commang线解析器)和getter(算法函数)来访问。 QVariant应该没问题。由于您的选项有名称,它们也具有隐式类型。 Getter应该通过名称检索值并明确进行类型转换。安装员不应该在意 - QVariant会。

创建一个具有选项名称映射的单例实例。实施由GUI值更改信号触发的插槽,在地图中设置值。 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:我没有编译的代码,MEY有一些错别字。