Qt信号/插槽发送完整的结构

时间:2016-09-14 16:57:33

标签: c++ multithreading qt signals-slots qt-signals

我试图通过两个线程之间的信号/插槽发送一个结构,我的信号/插槽正确连接,我已经能够发送包含我的数据部分的QStrings但现在我需要发送整个东西和结构似乎最明智的。但是,当我尝试信号没有发送/收到。问题似乎只是发送/接收结构,我尝试了很多方法之前和之后的处理。

我不能使用像herehere这样的指针,因为我的数据生成得太快,内存被写入或释放(我已尝试使用指针并假设引用将同样受影响)。

我已将Q_DECLARE_METATYPE添加到我的结构中。我的结构现在只是一个小测试(稍后会放大)并且在它自己的头文件中。

#ifndef RETURNSTRUCT_H
#define RETURNSTRUCT_H

struct Datastruct
{
    int markeridone;
};

Q_DECLARE_METATYPE(Datastruct);

#endif //RETURNSTRUCT_H

为什么我的程序无法发送/接收结构?非常感谢任何帮助。

我正在使用Windows 7,MinGW 32位,Qt 5.7.0,Qt Creator 4.0.3

3 个答案:

答案 0 :(得分:10)

您的调试日志应警告您 - 您只能发送qt元系统已知的类型。使用Q_REGISTER_METATYPE,您最终会注册与定义所在的命名空间相关联的类型。

幸运的是,您可以告诉Qt您的结构如下:

// after QApplication was instantiated
qRegisterMetaType<Datastruct>("Datastruct");
// but before any class is instantiated that connects signals with this type

它不会尝试通过查看代码来推断命名空间。确保重新运行qmake(或者更好地进行干净),或者在使用QtCreator进行构建时可能会忽略它。

如果您以后碰巧通过信号传递类型的模板类,请确保也注册它们,因为即使Qt知道QList,它也不知道您的类型的QList:

qRegisterMetaType<QList<Datastruct>>("QList<Datastruct>");

另一方面说明:如果您#define类别名,请务必使用真实姓名注册。

#define std::shared_ptr model_ptr
// you can declare your signals like this:
void my_signal(model_ptr<my_model>);
// but have to register the type like this:
qRegisterMetaType<std::shared_ptr<my_model>>("std::shared_ptr<my_model>");

答案 1 :(得分:4)

暂时,使用宏Q_DECLARE_METATYPE声明QMetaType已知的结构

struct Datastruct
{
    int markeridone;
};

Q_DECLARE_METATYPE(Datastruct)

您可以通过QVariant发送此结构。很好,很简单。 在你的标题中声明:

signals:
    void sendDatastruct(QVariant data);

public slots:
    void getDatastruct(QVariant data);

在您的代码中使用信号:

.....
Datastruct ds;
.....
QVariant data;
data.setValue(ds);
emit sendDatastruct(data);  // now send signal
.....

使用插槽:

void MyObject::getDatastruct(QVariant data)
{
    Datastruct ds = data.value<Datastruct>();
    .....
    // now You can use structure in Your code
}

答案 2 :(得分:0)

在收到运行时警告时,如果没有一些mods,我将无法正常工作:

startsQObject :: connect:没有此类信号

我阅读了文档,发现您只能通过引用传递const值:

所以您最终得到:

/* myWorker Class Instance header .h */

struct notifyMsg_t
{
    QString m_TitleSuffix;
    QString m_MessageSuffix;
    int     m_errNumber;
};

Q_DECLARE_METATYPE(notifyMsg_t);

signals:
    void sendDatastruct(const QVariant&);

/* MainWindow Class instance Header .h*/
public slots:
    void getDatastruct(const QVariant& data);

/* MainWindow Implementation .cpp */

connect(myWorker,
        SIGNAL(sendDatastruct(const QVariant&)),
        this,
        SLOT(getDatastruct(const QVariant&))
        );


/* Worker implementation .cpp */

void Worker::notify(QString    TitleSuffix,
                    QString    MessageSuffix,
                    int        errNumber)
{
    notifyMsg_t notifyMsg;
    notifyMsg.m_TitleSuffix = TitleSuffix;
    notifyMsg.m_MessageSuffix = MessageSuffix;
    notifyMsg.m_errNumber = errNumber;


    QVariant data;
    data.setValue(notifyMsg);
    emit wrkrError_dbTaskSig(data);
}

此代码有效。

请注意,您不会在SIGNAL定义中包含虚拟变量,即

/ *此>> >> /(const QVariant&)

/ *不是这个>> * / const QVariant&data

别问我为什么。

最诚挚的问候

Rob