微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法使用 QML 远程对象进行连接并出现错误:“connectionToSource 为空”

如何解决无法使用 QML 远程对象进行连接并出现错误:“connectionToSource 为空”

我正在尝试使用 Qt 远程对象来创建客户端服务器应用程序。 但是遇到了“connectionToSource 为空”的问题。如何设置源连接?

我正在使用 .rep 文件创建服务器。我使用的代码如下:

数据模型

// Rep File (DataModel.rep)
class DataModel {
    PROP(double data)
}

服务器代码

// Databroadcaster class (Databroadcaster.h)
// Databroadcaster class inherits DataModelSimpleSource.h (generated from .rep file)    
    #include "rep_DataModel_Source.h"
    class Databroadcaster : public DataModelSimpleSource
    {
        Q_OBJECT
        public:
            Databroadcaster(QObject *parent = nullptr);
            ~Databroadcaster();
        void Initialize();
            private:
            int QScopedPointer<QRemoteObjectHost> remoteHost;
    }

// Databroadcaster.cpp

Databroadcaster::Databroadcaster(QObject *parent): DataModelSimpleSource(parent){}
Databroadcaster::~Databroadcaster(){}
void Databroadcaster::Initialize()
{
    remoteHost.reset(new QRemoteObjectHost(QUrl(QStringLiteral("local:mydata"))));
    remoteHost->enableRemoting(this,"DataModel");
}

// 服务器代码函数

#include <QCoreApplication>
#include "Databroadcaster.h"
int main(int argc,char *argv[])
{
    QCoreApplication a(argc,argv);
    Databroadcaster server;
    server.Initialize();    
    double count = 0.0;
    while(true)
    {
        server.pushData(count + 0.1);
    }   
    return a.exec();
}

客户代码

// DataModelDataReplica is generated from .rep file used to generate source
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "rep_DataModel_replica.h"

int main(int argc,char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6,0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc,argv);
    QQmlApplicationEngine engine;
    // registered as qml type in main
    qmlRegisterType<DataModelReplica>("CustomData",1,"MyData");
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine,&QQmlApplicationEngine::objectCreated,&app,[url](QObject *obj,const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    },Qt::QueuedConnection);
    engine.load(url);
    return app.exec();
}

QML 代码

// displayPage.qml Added to QML file    
import CustomData 1.0    
MyData {
    id: dataClient
    node: Node {
        registerUrl: "local:mydata"
    }
    Button {
        id: btn
        text: "Server Data" 
        onClicked: {
            // displaying some data from source
            btn.text = dataClient.data
        }
    }
}

执行:

Server code is running
Client code is running but when trying to get data I get following error message in debugger
**"qt.remoteobjects: connectionToSource is null"**

我无法弄清楚我错过了什么。 如果有人对如何解决或在哪里寻找有任何想法,请提出建议。

解决方法

我能够找到问题所在。在服务器代码主函数中,使用了永远不会退出的 while 循环,因为“exec()”函数永远不会被调用,Qt 事件循环也永远不会启动,因为 Qt Remote 对象没有共享数据。所以我使用Signal and Slot机制修改了下面的代码,创建了一个非阻塞函数。以下是我所做的代码更改。

// 服务器代码主函数

#include <QCoreApplication>
#include "DataBroadcaster.h"
#include "ServerController.h"

int main(int argc,char *argv[])
{
    QCoreApplication a(argc,argv);
    DataBroadcaster server;
    server.Initialize(); 
    ServerController controller(&server);
    return a.exec();
}

// 服务器控制器

#include <QTimer>
#include "DataBroadcaster.h"

class ServerController : public QObject
{
Q_OBJECT
public:
    explicit ServerController(QObject *parent = nullptr,DataBroadcast *server = nullptr);
    ~ServerController();

public Q_SLOTS:
    void SendData();

private:
    QTimer timer;
    double count = 0.0; 
    DataBroadcast *m_server = nullptr;
}

ServerController::ServerController(QObject *parent,DataBroadcast *server): QObject(parent),m_server(server)
{
    connect(&timer,SIGNAL(timeout()),this,SLOT(SendData()));
    timer.start();
}

ServerController::~ServerController()
{
    timer.stop();
}

ServerController::SendData()
{
    count += 0.1;
    if(m_server != nullptr)
    {
         m_server->pushData(count);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。