Qt Signal/Slots 发送完整结构
Qt Signal/Slots sending a complete structure
我正在尝试通过 signals/slots 在两个线程之间发送一个结构,我的 signals/slots 已正确连接并且我已经能够发送包含部分数据的 QString,但现在我需要发送整个事情和结构似乎最明智。但是,当我尝试时,信号不是 sent/recieved。问题似乎只是sending/receiving结构,前后处理我试过很多方法。
我不能使用 here or here 这样的指针,因为我的数据生成速度太快,内存被写入或释放(我已经尝试过使用指针并假设引用会受到类似影响)。
我已经将 Q_DECLARE_METATYPE 添加到我的结构中。我的结构暂时只是一个小测试(后面会放大),在自己的头文件中。
#ifndef RETURNSTRUCT_H
#define RETURNSTRUCT_H
struct Datastruct
{
int markeridone;
};
Q_DECLARE_METATYPE(Datastruct);
#endif //RETURNSTRUCT_H
为什么我的程序可能无法 send/receive 结构?非常感谢任何帮助。
我正在使用 windows 7、MinGW 32 位、Qt 5.7.0、Qt Creator 4.0.3
您的调试日志应该警告您 - 您只能发送 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 构建时可能会被忽略。
如果您稍后碰巧通过信号传递您类型的模板-classes,请确保也注册它们,因为即使 Qt 知道 QList,它也不知道您类型的 QList:
qRegisterMetaType<QList<Datastruct>>("QList<Datastruct>");
另请注意:如果您#define class 别名,请务必使用真实姓名注册。
#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>");
此刻,当您使用宏声明 QMetaType 已知的结构时 Q_DECLARE_METATYPE
struct Datastruct
{
int markeridone;
};
Q_DECLARE_METATYPE(Datastruct)
您可以通过 QVariant 发送此结构。很好,很简单。
在您的 headers 声明中:
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
}
没有一些模组我无法让它工作,因为我收到了运行时警告:
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
别问我为什么。
此致
罗布
我正在尝试通过 signals/slots 在两个线程之间发送一个结构,我的 signals/slots 已正确连接并且我已经能够发送包含部分数据的 QString,但现在我需要发送整个事情和结构似乎最明智。但是,当我尝试时,信号不是 sent/recieved。问题似乎只是sending/receiving结构,前后处理我试过很多方法。
我不能使用 here or here 这样的指针,因为我的数据生成速度太快,内存被写入或释放(我已经尝试过使用指针并假设引用会受到类似影响)。
我已经将 Q_DECLARE_METATYPE 添加到我的结构中。我的结构暂时只是一个小测试(后面会放大),在自己的头文件中。
#ifndef RETURNSTRUCT_H
#define RETURNSTRUCT_H
struct Datastruct
{
int markeridone;
};
Q_DECLARE_METATYPE(Datastruct);
#endif //RETURNSTRUCT_H
为什么我的程序可能无法 send/receive 结构?非常感谢任何帮助。
我正在使用 windows 7、MinGW 32 位、Qt 5.7.0、Qt Creator 4.0.3
您的调试日志应该警告您 - 您只能发送 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 构建时可能会被忽略。
如果您稍后碰巧通过信号传递您类型的模板-classes,请确保也注册它们,因为即使 Qt 知道 QList,它也不知道您类型的 QList:
qRegisterMetaType<QList<Datastruct>>("QList<Datastruct>");
另请注意:如果您#define class 别名,请务必使用真实姓名注册。
#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>");
此刻,当您使用宏声明 QMetaType 已知的结构时 Q_DECLARE_METATYPE
struct Datastruct
{
int markeridone;
};
Q_DECLARE_METATYPE(Datastruct)
您可以通过 QVariant 发送此结构。很好,很简单。 在您的 headers 声明中:
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
}
没有一些模组我无法让它工作,因为我收到了运行时警告:
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
别问我为什么。
此致
罗布