您认为在不重复代码的情况下在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布局太复杂而无法通过代码进行设计。
谢谢。
答案 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时会出现其他问题。
所以DataA
和DataB
来自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派生组件。所涉及的课程包括ComponentA1
,ComponentA2
,ComponentB
等等。
使用抽象接口PluggableInterface
和UI组件将阻止ContainerDialog
知道正在使用哪种具体类,并且可以实现实例化特定类的所有必要代码使用一些创作模式(抽象工厂,原型等...)