Qt C++根据组合框中的选择创建一个对象

Posted

技术标签:

【中文标题】Qt C++根据组合框中的选择创建一个对象【英文标题】:Qt C++ creating an Object according to choice in combobox 【发布时间】:2017-01-09 09:26:01 【问题描述】:

由于我对面向对象代码的设计不是很有经验,所以我有以下问题:

我有一个组合框 cb_GRAN,其中包含代表 21 个几何图形的 21 个条目。根据 cb_GRAN 中所做的选择,我想开始对几何体表面进行不同的计算(实际上还有更多:更复杂的计算,LineEdits 的开/关等,但为了保持简单,让`s只是说表面的计算。)

为了解决这个问题,我创建了一个几何类和 21 个继承自几何的类(Geo_1、Geo_2、...Geo_21)。我也有虚方法

virtual void calculateSurface();

要定义哪个类Geo_x要创建和计算表面,我想出了以下想法:

Geometry *GEO;
QVector < Geometry*> qvec_GEO      

qvec_GEO << new Geo_1()<< new Geo_2()<< new Geo_3()<<......  << new Geo_21() ;

GEO =  qvec_GEO[ui->cb_GRAN->currentIndex()];
GEO->calculateSurface();
这是否是解决我的问题的可行方法,还是我这样做时会遇到问题? 创造尽可能多的东西是个好主意吗? 21 个对象,而我只需要一个?

【问题讨论】:

为什么不简单地使用 "switch (currentIndex()) case 0: GEO = new Geo_1(); break; case 1: ..." 或类似的东西?也许在某些功能?一个更好的解决方案可能是切换组合框的内容,即在 QString 上,这样如果项目以另一个顺序放置,它仍然会做它应该做的事情。无法识别项目时出现错误。我不太赞成没有内在意义的 indizes。顺便说一句,用大写字母命名局部变量并不常见。 【参考方案1】:

问题 1: 您的解决方案可能会运行良好(仅基于您提供的信息)。

问题 2: 你是完全正确的,如果你打算只使用其中的 1 或 2 个类,创建所有 21 个类的实例可能是矫枉过正。

您必须找到一种解决方案来仅实例化所需的类。 Qt 提供了一个您可以使用的元对象系统。基本上,您必须使用QMetaType class。

首先,您必须在元对象系统中注册“Geo_N”类。您有很多解决方案可以做到这一点,但在您的情况下,最好的办法是在类定义之后使用声明性宏:

class Geo_1 
    Q_OBJECT
    void Geo_1();
;
Q_DECLARE_METATYPE(Geo_1);

请注意,如果您想在元对象注册表中注册一个类,Q_OBJECT 宏是必需的。

然后,您将能够动态地实例化任何已注册的类型:

// The index of selected class (between 1 and 21)
int geoIndex = ui->cb_GRAN->currentIndex();

// Re-build the corresponding class name
QString typeName = "Geo_" + QString::number(geoIndex);

// Retrieve the type ID corresponding to the type name
int typeId = QMetaType::type(typeName.toStdString().c_str());

// Instantiate the corresponding class
Geometry* geo = (Geometry*) QMetaType::construct(typeId);

【讨论】:

感谢 Antwane 的回答。我试过了,但最后一行出现错误:“ create ”不是 QMetaType 的成员 你使用什么 Qt 版本? 我使用 Qt 4.8.4 和 Qt creator 2.8.1 尝试 QMetaType::construct(typeId) 而不是 create(这是 Qt 5 的正确方法) 我仍然有问题:我更改了 QString typeName = "Geo_" + QString::number(geoIndex) 因为否则我得到 typeName 的 "eo_" 然后我有一个问题:int typeId = QMetaType::type (typeName.toUtf8().data());它总是返回 0。当我想运行我的 Geo_x-Object 的方法时,程序崩溃了。【参考方案2】:

我的方法是为您的几何图形定义一个工厂类

class GeoFactory
  enum GeometryType  GEO_1, GEO_2, ... );
  std::uique_ptr<Geometry> create( GeometryType type );

然后将 GeometryType 添加到数据角色中的组合框项中。在当前更改的事件中,您只需从当前索引中检索 GeometryType 并从工厂请求相应的对象。

就我个人而言,我总是试图让 Qt 远离实际的业务逻辑,我只用于 UI。

【讨论】:

以上是关于Qt C++根据组合框中的选择创建一个对象的主要内容,如果未能解决你的问题,请参考以下文章

根据组合框中的是/否值逐行更新表格列

如何根据从其他框中选择的文本更改动态创建的组合框的显示项

如何根据用户表单组合框选择查询单元格中的数据并将数据复制到用户表单文本框中

用于打开报告的组合框 - 无法选择组合框中的项目

PyQt5:根据选择的元素与数据框中的另一个元素匹配设置自定义组合框文本的字体颜色

使用组合框中的选择填充文本框中的计算字段