2011-12-12 81 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这样的设计模式,现在真正理解了你们所有的真正含义。幸运的是,由于真实数据和用户界面之间存在一些“层次”,所以我的代码并非如此,因此修复错误很容易。非常感谢你,请原谅我这么晚回答 –