QDataStream 正在变为只读
Posted
技术标签:
【中文标题】QDataStream 正在变为只读【英文标题】:QDataStream is becoming Readonly 【发布时间】:2016-06-16 05:33:04 【问题描述】:我有两个名为 IPCBase 和 DispatchData 的类。现在我想将 QDataStrean Object drom IPCBase 传递给 DispatchData。首先,我尝试使用 Connect Statement 直接发送它。但它给出了错误,例如 QDataStream 对象未在 QRegisterMatatype 中注册。
edit :: 我也参考了这个链接
When, where and why use namespace when registering custom types for Qt
所以我做了类似的事情
typedef QDataStream* myDataStrem;
Q_DECLARE_METATYPE(myDataStrem)
然后在另一个类中连接语句(DispatchData)
connect(mpThrIPCReceiver, SIGNAL(dispatchReadData(const int&, myDataStrem)),
this, SLOT(onIPCDataReceived(const int&, myDataStrem)));
onIPCDataReceived 插槽
void DispatchData::onIPCDataReceived(const int& msgType, myDataStrem dataReceived)
// dataReceived >> str1; Here it is giving error
// qDebug()<<"is"<<str1;
MemberFuncPointer f = mIPCCommandMapper.value(msgType);
(this->*f)(*dataReceived);
//This is function pointer which will rout it to respective function depending on the Message type.
然后它会来这里
void DispatchData::onStartCountingCycle(QDataStream &dataReceived)
int data = 0;
dataReceived >> data; //Here it is crashing
//Giving error like
//pure virtual method called
//terminate called without an active exception
// I have debugged it and here dataReceived is becoming Readonly.
【问题讨论】:
我可以帮助你,但请提供一个有效的例子! 您似乎正在使用线程,这就是为什么它会自动使您的连接成为排队连接。在这种情况下,您将不得不为QDataStream
致电 qRegisterMetatype
,因为您收到的消息会告诉您。但这对我来说仍然很奇怪,你为什么要跨线程发送QDataStream
对象?解释一下你实际上想做什么,这对我来说就像一个XY problem。
@thuga 这里不需要qRegisterMetatype
。
@KubaOber 没错,我刚刚收到了他收到的错误消息。
【参考方案1】:
您似乎在传递一个悬空指针:当接收线程到达数据流时,它似乎不再存在。即使您在源对象中延长了它的生命周期,通过信号槽连接传递原始指针也是一个坏主意。如果源类可能在接收者线程有一个挂起的槽调用时消失,你仍然会在接收者处使用一个悬空指针。最好通过 QSharedPointer
或 std::shared_ptr
为您服务。
下面的作品,你当然可以在共享指针中使用任何类型。
#include <QtCore>
#include <cstdio>
struct Class : public QObject
Q_SIGNAL void source(QSharedPointer<QTextStream>);
Q_SLOT void destination(QSharedPointer<QTextStream> stream)
*stream << "Hello" << endl;
Q_OBJECT
;
Q_DECLARE_METATYPE(QSharedPointer<QTextStream>)
int main(int argc, char ** argv)
QCoreApplication appargc, argv;
Class c;
c.connect(&c, &Class::source, &c, &Class::destination, Qt::QueuedConnection);
auto out = QSharedPointer<QTextStream>(new QTextStream(stdout));
emit c.source(out);
QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection);
*out << "About to exec" << endl;
return app.exec();
#include "main.moc"
输出:
About to exec
Hello
在现代 Qt(至少 5.6)上,在这种情况下您不需要调用 qRegisterMetatype
。
同样使用std::shared_ptr
:
// https://github.com/KubaO/***n/tree/master/questions/datastream-pass-37850584
#include <QtCore>
#include <cstdio>
#include <memory>
struct Class : public QObject
Q_SIGNAL void source(std::shared_ptr<QTextStream>);
Q_SLOT void destination(std::shared_ptr<QTextStream> stream)
*stream << "Hello" << endl;
Q_OBJECT
;
Q_DECLARE_METATYPE(std::shared_ptr<QTextStream>)
int main(int argc, char ** argv)
QCoreApplication appargc, argv;
Class c;
c.connect(&c, &Class::source, &c, &Class::destination, Qt::QueuedConnection);
auto out = std::make_shared<QTextStream>(stdout);
emit c.source(out);
QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection);
*out << "About to exec" << endl;
return app.exec();
#include "main.moc"
【讨论】:
以上是关于QDataStream 正在变为只读的主要内容,如果未能解决你的问题,请参考以下文章
如何使用自定义指令使材料 <input matInput> 变为只读?