Qt5和Pattern用于类似的对话框实现

时间:2015-03-04 16:33:12

标签: c++ qt oop design-patterns ooad

您认为在不重复代码的情况下在Qt5中实现类似对话框的最佳方法是什么?

这就是问题:拥有两个“略有不同”的数据结构,有许多常见部分,实现两个“略有不同”的QDialog来处理用户交互。

我们有两种结构:

class DataA {
public:
  int one, two, three;
  bool x,y;
  SubdataA subA;
}

class DataB {
public:
  int one, two, three;
  bool x,y;
  SubdataB subB;
}

SubdataX是我们需要在GUI中处理的一些其他结构化数据。两个QDialog应该以相同的方式处理公共字段,而SubdataX必须由特定部分处理。代码还应对数据结构进行一些操作,并提供输出文件。这部分很容易。

我的问题是,实施此策略的最佳策略是什么?目标是拥有优雅的代码,这些代码应该非常易于维护并且尽可能地具有可读性。框架是Qt,所以解决方案应该在UI文件中使用qdialog布局定制到Qt,因为gui布局太复杂而无法通过代码进行设计。

谢谢。

2 个答案:

答案 0 :(得分:1)

我不确定你的意思是什么"很难管理祖先课程"。我想我明白你想要一个多态输入来确定对话框的布局。这个假设是否正确?

例如,给定以下类,您可以使用动态强制转换来影响对话框的行为。

class IData {
public;
    int one, two, three;
    bool x, y;
};

class DataA : public IData {
public:
    // more data in here
};

class DataB : public IData {
public:
     // more unique data in here
}

现在,假设您已经编写了一个带有函数签名的对话框

void configureDialog(IData *data) {
    DataA *dataA = dynamic_cast<DataA*>(data);
    if (dataA) {
        // configure what parts of the QDialog to see here
    }

    DataB *dataB = dynamic_cast<DataB*>(data);
    if (dataB) {
        // configure other parts of the QDialog you want to see
    }
}

这将允许单个QDialog框的多态配置。

答案 1 :(得分:0)

正如Tyler Jandreau所说,可能的解决方案是使用多态性。

但这需要仔细规划体系结构和类继承,因为为了避免使用向下转换和大量且不可维护的switch()情况,您还需要在GUI类上使用多态。

正如View / Model架构所要求的那样,控件/ Gui类将模仿数据类。

数据类将使用祖先,抽象类CommonData实现,包括公共&#34;字段&#34;,以及从CommonData通过继承派生的两个(或更多)具体数据类。我的第一个想法是使用合成,但是在实现gui时会出现其他问题。

所以DataADataB来自CommonData

在Gui方面,结构类似,但由于缺乏对Qt uic生成的UI表单类的继承支持,我们不能使用继承。我的第一个猜测是使用模板元编程,并将祖先类实现为Template类,但尽管它在C ++端工作,moc拒绝解析该类并在moc_X文件时生成Q_OBJECT文件{1}}标记的类是一个模板。

所以我们将使用继承和组合的混合。

这是架构:a&#34;容器&#34; GUI类(ContainerDialog)实现CommonData类的GUI; PluggableInterface抽象类将定义一组操作(我们将在下面看到);从后者派生的一组具体类将实现其余类的GUI逻辑。

因此ContainerDialog加载ContainerDialog.ui表单作为&#34;标准&#34; QDialog,并管理CommonData的所有界面。他的构造函数或setter将收到CommonData指针,请记住CommonData是抽象的,无法实例化。

特定字段由特定的图形组件管理,这些组件是&#34;插入的&#34;在ContainerDialog gui中。例如,PluggableInterface中定义的方法将在ContainerDialog gui中插入QWidget派生组件。所涉及的课程包括ComponentA1ComponentA2ComponentB等等。

使用抽象接口PluggableInterface和UI组件将阻止ContainerDialog知道正在使用哪种具体类,并且可以实现实例化特定类的所有必要代码使用一些创作模式(抽象工厂,原型等...)