程序选项

时间:2013-06-25 15:00:17

标签: c++ qt

我正在使用C ++进行一些算法工作。我的算法有一些选项,我需要尽可能少的努力添加到我的程序。我目前正在使用this代码。

一切都按预期工作:我在程序中添加了一些代码,因此我可以使用-oopt1=val1,opt2=val2等参数调用二进制文件,并自动设置选项。

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

但是,我不希望在我声明我的选项的标题中有任何特定于GUI的代码,因为我想将GUI与程序的其余部分分开。我可以将任何Option子类化为创建适当的QWidget*,但如果我得到OptBase*的列表,我就不知道应该创建哪种小部件。

是否有某些方法可以让GUI与程序的其余部分分开,同时仍然能够创建适当的小部件?

2 个答案:

答案 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。:我没有编译代码,但是有一些错别字。