2013-06-25 88 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有一些錯別字。