如何在多个线程中使用模板类型作为插槽和信号参数?

时间:2014-10-14 14:59:39

标签: c++ qt templates signals-slots

我可以以任何方式使用模板类型作为插槽或信号参数吗?例如,我试图定义以下内容:

void exampleSignal(std::map<non_template_type_1,non_template_type_2> arg);
void exampleSlot(std::map<non_template_type_1,non_template_type_2> arg);

这会在运行时产生以下结果:

QObject::connect: Cannot queue arguments of type 
    'std::map<non_template_type_1,non_template_type_2>'
(Make sure 'std::map<non_template_type_1,non_template_type_2>' 
    is registered using qRegisterMetaType().)

尝试向std::map<non_template_type_1,non_template_type_2>注册Q_DECLARE_METATYPE()会导致编译失败,显然不受支持。

作为解决方法,我使用QVariantMap代替std::map。但我真的想知道解决这个问题的正确方法;一个无法修改模板类的地方。

编辑:我忘了提到信号和插槽是在不同的线程中发出和接收的。显然,运行时错误不会发生在单线程场景中。

3 个答案:

答案 0 :(得分:3)

这对我有用:

qRegisterMetaType< std::vector<float> >( "std::vector<float>" );
qRegisterMetaType< std::vector<int>   >( "std::vector<int>"   );
qRegisterMetaType< std::map<std::string,int64_t> >( "std::map<std::string,int64_t>" );

答案 1 :(得分:2)

正如this thread中所述,您可以尝试使用typedef,包括QMetaType标题,然后使用Q_DECLARE_METATYPE宏和qRegisterMetaType函数(如this thread对类似问题的暗示。)

答案 2 :(得分:1)

如果您创建了这样的类并使用Qt moc编译器自动创建QMetaObject,则没有问题:

class MyClass : public QObject
{
    Q_OBJECT
public:
    explicit MyClass(QObject *parent = 0)
        : QObject(parent)
    {
    }
public slots:
    void exampleSlot(std::map<non_template_type_1,non_template_type_2> arg);
signals:
    void exampleSignal(std::map<non_template_type_1,non_template_type_2> arg);
};

当然,您需要包含QObject以及std::map所在的位置。