c++ - 如何通过插件机制在运行时动态加载数据类型

标签 c++ list qt metadata slot

由于 Qt 不允许在其插槽中使用模板,因此我尝试执行以下解决方案但没有成功。

首先,我想创建一个这样的列表:

list commands = 
0, "MyDashboard", DashBoard0
1, "MomsDashboard", Dashboard1

Dashboard 0 和 1 均源自 widget

假设您有一个 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# 类型中那样创建列表和存储类型?

最佳答案

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# 中的反射功能。这就是为什么您必须求助于工厂方法和抽象工厂等模式。


附录

我还没有意识到 Qt 可能会提供超出 C++ 中通常可用的运行时类信息(我只将 Qt 用于简单的实用程序应用程序,所以我不知道该框架中可用的所有花哨功能) 。考虑到这一点,我搜索并找到了这个邮件列表 discussion关于如何通过类名实例化 Qt 对象。不过,我不知道该解决方案是否适用于插件对象。

关于c++ - 如何通过插件机制在运行时动态加载数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9206111/

相关文章:

c++ - 我的神经网络导致堆栈溢出

c++ - 如何在不使用结尾的分隔符的情况下从字符串构建逗号分隔的列表?

qt - 在一个 QTableView 单元格中带有图像的超链接

c++ - 如何使用 QTcpSocket 获取 Protobuf 发送的数据

c++ - auto的推导使编译器生成默认构造函数

java - 如何在java代码中使用scala.collection.immutable.List数组

Python循环比较字典列表与另一个字典

multithreading - Qt GUI 中许多小部件的快速更新

c++ - Qt msvc2013 使用 vs2015 构建

c++ - STL容器插入元素和内存透视图