Advice about sharing class members
-
Hi everybody..
I'm developing an application using Qt, but I need some advices regarding sharing class members.
I am working with some collections (QHash) of project-specific structs and I created a polymorphic class to manage those collections. A derived class also manage some UI components (shared through pointers or references) so it can automatically represent those structs in the UI.. It's something like this:Main class
@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;
}@
Base class for collection managing..
@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;
}@Derived class for UI management and so on
@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;
};@And I share some UI members in the constructor of the MainWindow class..
@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 ..
}@
I call the functions from the StructEditor class when I need to add a new Category or something like that..
My project consists of three applications, those of which use almost the same methods for managing these structs, so I decided to use a class with the methods to add, update, remove and represent the structs in the UI sharing some member pointers with the MainWindow class. But now I'm thinking it is a bit dirty and I should not share these members because the MainWindow loses control over them. I was thinking I could create the collections of my structs in the Base class and make a method so I can read (securely) members of those collections in the MainWindow class, but my problem is with UI members. I could use signals and manage those members directly in the MainWindow class, but then I would have to duplicate a lot of code and it would complicate (a bit) the code changes, which is the main reason I decided to unify those methods in a class.So, my question is: Is there any way to 'unify' those methods without having to share members or using ugly global variables? I would like to have those methods in a separated file.
Thanks and greetings!
-
No one? Please, I can't figure out how to do it in "the clean way".
Thanks!
-
[quote author="Danielc" date="1323714777"]No one? Please, I can't figure out how to do it in "the clean way".
Thanks![/quote]
Please be patient. Pushing an unanswered topic is usually acceptable after waiting a few days or a week, not after a few hours. Thanks.
-
Excuse me, Volker.
I was wondering if it would be better to share a reference to the UI widgets only when I need to modify them rather than storing pointers. How good is it?
For example:
Actual code..
@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;
};@New code..
@class StructEditor : public StructManager
{
Q_OBJECT
public:StructEditor(QWidget* parent = 0); // ...Overriden functions to automatically represent structs in the shared members.. addCategory(QTreeWidget& catList); // Just example.. More arguments should be here.
};@
-
Why don't you let your manager to emit signals that can be caught by the mainwindow that will update the UI accordingly? So the struct manager will be the only one that operates on your data model and your main window will be the only one that translates the model into a gui. A more complex approach would be to build a model around your structures. By the way, using signals will not be a lot of code (sounds like a CRUD set of operations to me - with the concrete structure as parameter).
-
Yes, it is a good alternative to sharing members, but anyway I would have to define those functions at least three times. I want to define them only once, but in a cleaner way.
Thanks for your answer.
Greetings!
-
[quote author="Danielc" date="1323885576"]but anyway I would have to define those functions at least three times. [/quote]
Why three times? If your manager emits a signal of type "create" with the structure created as paramater, you will have to implement a method. The same for editing, deleting, but it will always be a single method implementation for each operation. Am I loosing something?
-
Hi again!
I would have to define such methods three times because I would have to access to the ui members from the form class (as I don't want to share them).
Thanks and greetings!
-
Uhm...I'm really not getting what you are trying to do. It seems to me that you are calling for troubles if you are not going to share the model with the UI, by the way it would be my fault not understanding your design choice.
-
Don't worry. Finally I created a QWidget derived class for each struct I wanted to represent (separating the previous StructEditor class) and a Collection class for each struct (separating the previous StructManager class). Then I connect the Collection classes with the QWidget classes (the UI representation) using signals/slots!. By this way I kept encapsulation without repeating code, and also the UI is separated from data (something like MVC).
Greetings!