1

我不需要经常创建 GUI,但今天我这样做了,我希望能得到一些设计输入。

基本上我有一个后端,我也打算使用 MVC 模式添加一个 GUI。问题是我觉得封装主 GUI 窗口的任何类都会有很多状态(所有子元素);最重要的是,它将有很多 setter,可能还有 getter、clear、color、size、position 和 refresh 功能。

  • 一种选择是推进这个想法,并拥有一个非常大的公共界面来处理 GUI 使用的类型(std::string... std::vector<std::string>),我希望对 UI 的控制越多,我需要的公共成员函数就越多。

  • 另一种选择是将程序状态传递给 GUI 并让它决定如何显示它,我担心这样做意味着它会给我更少的细节控制,并且会破坏关注点的分离,并意味着对程序状态的表示也需要在 GUI 中进行更改。

关于此事的任何意见都会有很大帮助。

如果有什么不同,这是一个使用 ncurses 抽象的 C++ gui。

4

3 回答 3

2

在我看来,您对 M 和 V 考虑了很多,但对 C 考虑不多。该模式应该真正称为 MCV,因为整个想法是控制器是模型(数据)和视图之间的桥梁(图形用户界面)。听起来您需要一个具有您提到的大部分功能的控制器。

简而言之,您的模型显然应该对显示一无所知,并且您的显示(视图)不应该知道如何访问模型。您需要一个控制器来读取数据(模型)并向显示器(视图)提供指令。如果您在视图中有用户交互,控制器可以解释它并根据需要修改模型。

这个想法是您永远不必更改所有 3,但是如果您更改模型或视图,您几乎总是必须更新控制器。

希望有帮助...

于 2013-03-01T20:36:58.260 回答
0

巨型界面至少有一种替代方案。与其拥有一个处理每件事(大小、字体、颜色、要显示的内容等)的函数,不如拥有一个接受“角色”和代表角色的数据的单一函数。这需要某种可以包含多种数据类型的包装器。

QT 的 QAbstractItemModel 类参考有一个很好的例子:

QVariant QAbstractItemModel::data ( const QModelIndex & index, int role = Qt::DisplayRole ) const [纯虚拟]

该函数将返回 QVariant,该 QVariant 表示在提供的索引处指示的角色。

这种方法的缺点是您必须知道存在哪些角色以及它们的作用。 QT 的默认角色如下所示。

于 2013-03-01T20:54:06.993 回答
0

我喜欢让模型的某些部分能够自我检测:

class Model {
private:
    int value;
public:
    void instrument(Instrumenter& instrumenter);
};

管理控件的Instrumenter创建。该模型将告诉它如何控制它并允许它访问数据。

void Model::instrument(Instrumenter& instrumenter) {
    instrumenter.addRangeController(0, 100, 5, value);
}

然后针对不同的输入设备(例如键盘、触摸屏),您可以创建适当的控件:

class KeyboardInstrumenter : public Instrumenter {
public:
    void addRangeController(int min, int max, int increments, int& controlled) {
        // create 3 widgets, up arrow, down arrow, and value
    }
};

class TouchscreenInstrumenter : public Instrumenter {
public:
    void addRangeController(int min, int max, int increments, int& controlled) {
        // create slider with min, max and increments
    }
};

int我们可以将它包装在一个控制对象中,而不是直接传入,以帮助封装。

于 2013-03-01T21:53:25.560 回答