由于Qt不允许在其插槽中使用模板,因此我尝试执行以下解决方案但未成功。
首先想创建一个这样的列表:
list commands =
0, "MyDashboard", DashBoard0
1, "MomsDashboard", Dashboard1
仪表板0和1均来自小部件
假设您有QListWidget
我们在列表中添加字符串然后进行连接:
connect(listWidget, SIGNAL(itemClicked(QListWidgetItem*)),
this, SLOT(addDashboard(QListWidgetItem*)));
void addDashboard(QListWidgetItem* item) {
int index = listWidget->row(item);
QWidget* widget = new typeof(command.atIndex(index).getType());
widget->show();
}
我如何像在C#Type中那样创建列表和存储类型?
答案 0 :(得分:3)
C ++不允许您创建一个对象(使用new运算符),其中类型仅在运行时已知。但是,您可以使用简化形式的Factory Method模式作为解决方法。
以下是一个例子:
// Type IDs that are associated with a widget type
enum WidgetTypeId {
dashboard1WidgetTypeId,
dashboard2WidgetTypeId
};
// Factory method
QWidget* createWidget(WidgetTypeId type) {
switch (type)
{
case dashboard1WidgetTypeId:
return new DashBoard0;
case dashboard2WidgetTypeId:
return new DashBoard1;
}
}
void addDashboard(QListWidgetItem* item) {
int index = listWidget->row(item);
QWidget* widget = createWidget(command.atIndex(index).getWidgetTypeId());
widget->show();
}
不是很漂亮,我知道。如果您的小部件是可克隆的,则可以使用std::map
而不是丑陋的switch语句。这种替代方法将是Prototype Pattern的一个例子。以下是一些显示此方法的示例代码:
class WidgetFactory
{
public:
QWidget* create(const std::string& name) {
return prototypes_[name]->clone();
}
void addPrototype(const std::string& name, QWidget* prototype) {
prototypes_[name] = prototype;
}
private:
std::map<std::string, QWidget*> prototypes_;
}
WidgetFactory factory;
factory.addPrototype("DashBoard0", new DashBoard0);
factory.addPrototype("DashBoard1", new DashBoard1);
void addDashboard(QListWidgetItem* item) {
int index = listWidget->row(item);
QWidget* widget = factory.create(command.atIndex(index).getWidgetTypeName());
widget->show();
}
C ++不是一种非常动态的语言。它限制了RTTI功能,几乎没有C#中的反射功能。这就是为什么你必须采用像Factory Method和Abstract Factory这样的模式。
<强>附录强>
我没有意识到Qt可能提供超出C ++中通常可用的运行时类信息(我只使用Qt用于简单的实用程序应用程序,所以我不知道该框架中可用的所有铃声和口哨声)。考虑到这一点,我搜索并找到了关于如何按类名实例化Qt对象的邮件列表discussion。我不知道该解决方案是否适用于插件对象。