我主要是一名 .Net 开发人员,并且已经研究 Qt 有一段时间了。我现在正处于尝试在 Qt 中实现模型/视图框架的阶段。我想我掌握了基本原理,但不清楚如何在一个更复杂的 UI 中将东西挂在一起,小部件需要相互通信。鉴于以下情况:
// 'domain' model classes
class NestedDomainModel1
{
public:
NestedDomainModel1();
QString name() const;
void setName(const QString& newName);
// other properties
private:
QString m_name;
};
class NestedDomainModel2
{
public:
NestedDomainModel2();
QString name() const;
void setName(const QString& newName);
// other properties
};
class MyDomainModel
{
public:
MyDomainModel();
void addNestedModel1(const NestedDomainModel1& modelToAdd);
NestedDomainModel& nestedObjectModel1At(int index);
int nestedObjectModel1Count() const;
// repeat for model 2
private:
QList<NestedDomainModel1> m_nestedModels1;
QList<NestedDomainModel2> m_nestedModels2;
};
// 'GUI' classes
class MainWindow : public QMainWindow
{
private:
MyDomainModel* m_model;
MyTreeViewWidget* m_treeWidget; // -> this sits in a left dock window
MyInfoDisplayWidget* m_infoWidget; // -> this sits in a right dock window and display details about the item selected in the tree
};
class MyDomainModelTreeModel : public QAbstractItemModel
{
public:
explicit MyDomainModelTreeModel(MyDomainModel* model);
// required overrides for QAbstractItemModel
private:
MyDomainModel* m_model;
};
class MyTreeViewWidget : public QWidget
{
public:
// Take a pointer to the domain model and create a model for the 'view'.
// Will create a tree like:
// Nested Objects 1
// |- object 001
// |- object 002
// |- you get the idea
// Nested Objects 2
// |- other object 001
// |- more of the same
explicit MyTreeViewWidget(MyDomainModel* model);
public slots:
// Used to notify widget when an item is added to the underlying model.
void nestedModel1Added();
void nestedModel2Added();
signals:
void nestedModel1Selected(NestedDomainModel1& selectedModel);
void nestedModel2Selected(NestedDomainModel2& selectedModel);
private slots:
// connect to tree view event when an item is selected and if all ok, emit one of the selected events
void onTreeItemSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
private:
QTreeView* m_treeView;
MyDomainModelTreeModel* m_treeModel;
};
class MyNestedClass1ViewModel : QAbstractItemModel
{
public:
explicit MyNestedClass1ViewModel(NestedDomainModel1* model);
setModel(NestedDomainModel1* model);
// required overrides for QAbstractItemModel
private:
NestedDomainModel1* m_model
};
class MyInfoDisplayWidget : public QWidget
{
public:
explicit MyInfoDisplayWidget(QWidget* parent = 0);
public slots:
// this is connected to the 'tree' widget signal in MainWindow
void setModel(NestedDomainModel1& selectedModel);
};
UI 的基本前提在感觉上类似于 Visual Studio。树类似于解决方案资源管理器,“信息显示”类似于属性窗口。
这就是你使用模型/视图框架的方式吗?对于那些熟悉 WPF/Silverlight 开发的人来说,模型/视图框架是否类似于 MVVM(在高层次上),因为它是“视图模型”并包装/包含域模型?
这是您使用模型/视图框架连接小部件的方式吗(即,一个小部件将模型的指针或引用传递给另一个小部件)?还是我应该使用 SelectionModel?由于树模型包含不同类型的对象,这是否有效?
如何识别根节点?例如,当创建 MyNestedObject1 并需要将其添加到树时,我是否依赖于根节点位于模型索引 QModelIndex(0, 0) 的知识(即第 0 行,父索引无效)?