2011-12-12 79 views
3

我剛剛在這裏註冊,所以在任何事情之前,感謝您的閱讀!如何合併使用私人會員的不同班級的相同方法

我正在開發一個使用Qt的應用程序,但我需要關於共享類成員的一些建議。 我正在使用項目特定結構的一些集合(QHash),並且我創建了一個多態類來管理這些集合。派生類還管理一些UI組件(通過指針或引用共享),因此它可以自動代表在UI的結構。它是這樣的:

主要類

class ArmyEditor : public QMainWindow 
{ 
//.... some specific functions ... 

private: 
    Ui::ArmyEditor *ui; 

    // Specific structs 
    QHash<QString, GameCategory> categories; 
    QHash<QString, Column> columns; 
    QHash<QString, GameProperty> properties; 
    QHash<QString, UnitOption> commonOptions; 
    QHash<QString, UnitOption> inheritedOptions; 
    QHash<QString, GameItem> items; 
    QHash<QString, GameItem> inheritedItems; 
    QHash<QString, GlobalText> globalTexts; 
    QHash<QString, GlobalText> inheritedGlobalTexts; 
    QHash<QString, Unit> units; 
}; 

基類集合管理..

class StructManager : public QObject { 
    Q_OBJECT 
public: 

    explicit StructManager(QWidget* parent = 0); 

    // ...Functions that perform actions in shared components... 

protected: 
    QWidget *parent; 
    QHash<QString, GameCategory> *categories; 
    QHash<QString, Column> *columns; 
    QHash<QString, GameProperty> *properties; 
    QHash<QString, UnitOption> *commonOptions; 
    QHash<QString, GameItem> *commonItems; 
    QHash<QString, GlobalText> *globalTexts; 
    QHash<QString, Unit> *units; 
}; 

的UI管理等派生類

class StructEditor : public StructManager 
{ 
    Q_OBJECT 
public: 

    StructEditor(QWidget* parent = 0); 

    // ...Overriden functions to automatically represent structs in the shared members.. 

protected: 
    QTreeWidget *catList; 
    QListWidget *colList; 
    QTreeWidget *propList; 
    QTreeWidget *optList; 
    QListWidget *optActionList; 
    QTreeWidget *itemList; 
    QListWidget *itemActionList; 
    QTableWidget *globalTextsGrid; 
    QTreeWidget *unitTree; 
    QComboBox *optCategory; 
    QComboBox *itemCategory; 
    QComboBox *unitCategory; 
    QComboBox *optAmountColumn; 
    QComboBox *optSetColumn; 
}; 

我在主窗口類的構造函數分享一些UI成員..

ArmyEditor::ArmyEditor(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::ArmyEditor) 
{ 
    ui->setupUi(this); 

    // Setup Army Struct Manager 

    armyManager = new StructEditor(this); 

    armyManager->setCatList(ui->catList); 
    armyManager->setOptList(ui->optList); 
    armyManager->setOptActionList(ui->optActionList); 
    armyManager->setItemList(ui->itemList); 
    armyManager->setItemActionList(ui->itemActionList); 
    armyManager->setGlobalTextsGrid(ui->globalTextsGrid); 
    armyManager->setUnitTree(ui->unitTree); 
    armyManager->setOptCategory(ui->optCategory); 
    armyManager->setItemCategory(ui->itemCategory); 
    armyManager->setUnitCategory(ui->unitCategory); 
    armyManager->setOptAmountColumn(ui->optAmountColumn); 
    armyManager->setOptSetColumn(ui->optSetColumn); 
    armyManager->setCategories(&categories); 
    armyManager->setOptions(&commonOptions); 
    armyManager->setItems(&items); 
    armyManager->setGlobalTexts(&globalTexts); 

    //.. some other code .. 
}; 

我打電話從StructEditor類的功能,當我需要添加一個新的類別或類似的東西.. 我的項目包括這三個應用程序使用幾乎相同的方法來管理這些結構,因此我決定使用一個帶有方法的類來添加,更新,移除和表示UI中與MainWindow類共享一些成員指針的結構。但是現在我認爲它有點髒,我不應該分享這些成員,因爲MainWindow失去了對它們的控制權。我以爲我可以在Base類中創建我的結構集合,並創建一個方法,以便我可以(安全地)讀取MainWindow類中的這些集合的成員,但是我的問題與UI成員有關。我可以使用信號並直接在MainWindow類中管理這些成員,但是我必須複製大量代碼,並且會使代碼更改複雜化(一點點),這是我決定統一這些方法的主要原因類。

所以,我的問題是:有沒有辦法'統一'這些方法,而不必共享成員或使用全局變量(因爲會有相同的效果)?我想將這些方法放在單獨的文件中。

感謝和問候!

+0

如果通過可以共享一個通用的接口,聽起來像是一個完美的時間,使一個庫項目(DLL或LIB)的應用程序都可以通過某種API的使用多個應用程序使用的類似的邏輯。 – AJG85

+0

@ AJG85謝謝您的回答!也許這是一個好主意,但我遇到了同樣的問題:修改UI會員沒有共享。我認爲「清潔」的解決方案將在主窗口類中這樣做(即控制用戶界面中的一個),但我不想重複相同的代碼.. 謝謝! –

+1

模型/視圖架構Qt中效果很好。一般來說,如果您的gui不與您的數據耦合,則更容易進行更改。 – AJG85

回答

0

您應該看看您提供的繼承和數據所在的位置。

由於AJG85指出你應該從你的操縱和視圖,以便例如解耦數據:

class StructManager { 
private: 
    typedef QHash<QString, GameCategory> CategoryT; 
    CategoryT categories; 
    .... 
public: 
    CategoryT& getCategories() { return categories; } 
}; 

class StructEditor : public QObject 
{ 
Q_OBJECT 
protected: 
    StructManager sm; 
... 
}; 

class ArmyEditor : public StructEditor 
{ 
public: 
    <manipulation methods> 
}; 

class ArmyWindow : public MainWindow 
{ 
private: 
    ArmyEditor ae; 
.... 
}; 

一旦你已經遵循了這一結構,你會發現,從UI的所有事件可以傳遞你的編輯器操縱數據並顯示讀取它的字段。

這樣你就沒有對象間的數據共享,也沒有代碼重複。如果你想真的很喜歡這樣做:

class BaseEditor 
{ 
protected: 
    void ManipulateCategories() = 0; 
}; 

class StructEditor : public QObject, public BaseEditor 
{ 
    .... 
}; 

class ArmyEditor : public QObject, public BaseEditor 
{ 
.... 
}; 

我相信你可以找出各個編輯器類的實現。

+0

只是想說,經過很多時間,我已經有了UI解耦的經驗,還有一些像MVC這樣的設計模式,現在真正理解了你們所有的真正含義。幸運的是,由於真實數據和用戶界面之間存在一些「層次」,所以我的代碼並非如此,因此修復錯誤很容易。非常感謝你,請原諒我這麼晚回答 –