Qt 中的 MVD 架构,即 Model-View-Delegate架构,是一种用于构建用户界面的设计模式。它将数据(Model)、数据的可视化展示(View)以及数据的编辑和渲染方式(Delegate)分离开来。Model 负责存储和管理数据;View 负责将数据以可视化的形式呈现给用户;Delegate 则负责处理数据在 View 中的编辑和显示细节。
MVD 架构的优势
- 高可维护性:由于各部分职责单一,当数据结构或显示方式发生变化时,只需修改对应的 Model 或 View 部分,而不会影响其他部分,降低了代码的耦合度。
- 代码复用:Model 和 View 可以被多个不同的界面复用。例如,同一个 Model 可以用于不同的表格视图或树形视图。
- 便于扩展:添加新的 View 或 Delegate 非常容易,无需对现有代码进行大量修改。比如,想要添加一个新的图表视图来展示数据,只需创建新的 View 类并关联到已有的 Model。
实现步骤
- 创建 Model:在 Qt 中,可以继承 QAbstractItemModel 类来创建自定义的 Model。需要实现一些纯虚函数,如 rowCount ()、columnCount ()、data ()、headerData () 等。
class MyModel : public QAbstractItemModel
{
Q_OBJECT
public:
MyModel(QObject *parent = nullptr);
~MyModel();
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
private:
// 存储数据的容器,例如QList>
};
- 创建 View:Qt 提供了多种预定义的 View 类,如 QListView、QTableView、QTreeView 等。可以直接使用这些类,也可以继承它们进行定制。
QTableView *tableView = new QTableView(this);
MyModel *model = new MyModel(this);
tableView->setModel(model);
- 创建 Delegate:继承 QStyledItemDelegate 类来创建自定义 Delegate。通常需要重写 paint () 和 createEditor () 函数。
class MyDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
MyDelegate(QObject *parent = nullptr);
~MyDelegate();
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
};
然后将 Delegate 设置到 View 上:
MyDelegate *delegate = new MyDelegate(this);
tableView->setItemDelegate(delegate);