Sur cette page

QtRemoteObjects Applications WebSockets

Utilisation d'un transport non basé surQIODevice(QWebSocket) avec QtRemoteObjects.

Cet exemple partage un site QStandardItemModel via une socket web. Le modèle peut être modifié dans la fenêtre de l'application wsserver, et les changements sont propagés dans la fenêtre de l'application wsclient.

Ceci est rendu possible par l'implémentation d'un petit wrapper dérivé de QIODevice, WebSocketIoDevice, pour QWebSocket. SSL est utilisé si Qt est compilé avec le support nécessaire.

Fenêtre SourceView avec tableau à deux colonnes et mise en évidence des lignes en couleur

L'application WsServer

L'application wsserver crée un QStandardItemModel avec deux colonnes et y insère des données.

int main(int argc, char *argv[])
{
    QLoggingCategory::setFilterRules("qt.remoteobjects.debug=false\n"
                                     "qt.remoteobjects.warning=false");
    QApplication app(argc, argv);

    const int modelSize = 100000;
    QStringList list;
    QStandardItemModel sourceModel;
    QStringList hHeaderList;
    hHeaderList << QStringLiteral("First Column with spacing") << QStringLiteral("Second Column with spacing");
    sourceModel.setHorizontalHeaderLabels(hHeaderList);
    list.reserve(modelSize);
    for (int i = 0; i < modelSize; ++i) {
        QStandardItem *firstItem = new QStandardItem(QStringLiteral("FancyTextNumber %1").arg(i));
        if (i == 0)
            firstItem->appendRow(addChild(2, 2));
        QStandardItem *secondItem = new QStandardItem(QStringLiteral("FancyRow2TextNumber %1").arg(i));
        if (i % 2 == 0)
            firstItem->setBackground(Qt::red);
        QList<QStandardItem*> row;
        row << firstItem << secondItem;
        sourceModel.invisibleRootItem()->appendRow(row);
        //sourceModel.appendRow(row);
        list << QStringLiteral("FancyTextNumber %1").arg(i);
    }

Elle démarre ensuite un QWebSocketServer lié au port 8088 et héberge le modèle de données.

QWebSocketServer webSockServer{QStringLiteral("WS QtRO"), QWebSocketServer::NonSecureMode};
webSockServer.listen(QHostAddress::Any, 8088);

QRemoteObjectHost hostNode;
hostNode.setHostUrl(webSockServer.serverAddress().toString(), QRemoteObjectHost::AllowExternalRegistration);

hostNode.enableRemoting(&sourceModel, QStringLiteral("RemoteModel"), roles);

Lors de la gestion de nouvelles connexions, SSL est configuré si Qt est compilé avec un support pour cela. Ensuite, une adresse WebSocketIoDevice est créée en utilisant la connexion WebSocketServer entrante.

    QObject::connect(&webSockServer, &QWebSocketServer::newConnection, &hostNode , [&hostNode, &webSockServer]{ while(auto conn = webSockServer.nextPendingConnection()) {#ifndef QT_NO_SSL // Toujours utiliser des connexions sécurisées lorsqu'elles sont disponibles          QSslConfiguration sslConf ; QFile certFile(QStringLiteral(":/sslcert/server.crt")) ; if (!certFile.open(QIODevice::ReadOnly))                qFatal("Can't open client.crt file");
            sslConf.setLocalCertificate(QSslCertificate{certFile.readAll()}) ; QFile keyFile(QStringLiteral(":/sslcert/server.key")) ; if (!keyFile.open(QIODevice::ReadOnly))                qFatal("Can't open client.key file");
            sslConf.setPrivateKey(QSslKey{keyFile.readAll(), QSsl::Rsa}) ; sslConf.setPeerVerifyMode(QSslSocket::VerifyPeer) ;  conn->setSslConfiguration(sslConf) ; QObject::connect(conn, &QWebSocket::sslErrors, conn, &QWebSocket::deleteLater) ;#endif     QObject::connect(conn, &QWebSocket::disconnected, conn, &QWebSocket::deleteLater) ; QObject::connect(conn, &QWebSocket::errorOccurred, conn, &QWebSocket::deleteLater) ; auto ioDevice = new WebSocketIoDevice(conn) ; QObject::connect(conn, &QWebSocket::destroyed, ioDevice, &WebSocketIoDevice::deleteLater) ; hostNode.addHostSideConnection(ioDevice) ; } }) ;

Un QTreeView est créé avec le QStandardItemModel comme modèle. Ensuite, plusieurs minuteries sont lancées à l'adresse QTimer::singleShot afin d'apporter d'autres modifications au modèle.

QTreeView view;
view.setWindowTitle(QStringLiteral("SourceView"));
view.setModel(&sourceModel);
view.show();
TimerHandler handler;
handler.model = &sourceModel;
QTimer::singleShot(5000, &handler, &TimerHandler::changeData);
QTimer::singleShot(10000, &handler, &TimerHandler::insertData);
QTimer::singleShot(11000, &handler, &TimerHandler::changeFlags);
QTimer::singleShot(12000, &handler, &TimerHandler::removeData);
QTimer::singleShot(13000, &handler, &TimerHandler::moveData);

return app.exec();

L'application WsClient

L'application wsclient crée un QWebSocket et un WebSocketIoDevice qu'elle prend en argument.

QScopedPointer<QWebSocket> webSocket{new QWebSocket};
WebSocketIoDevice socket(webSocket.data());

Si Qt est compilé avec le support de SSL, le client est configuré avec.

#ifndef QT_NO_SSL // Toujours utiliser des connexions sécurisées lorsqu'elles sont disponibles   QSslConfiguration sslConf ; QFile certFile(QStringLiteral(":/sslcert/client.crt")) ; if (!certFile.open(QIODevice::ReadOnly))        qFatal("Can't open client.crt file");
    sslConf.setLocalCertificate(QSslCertificate{certFile.readAll()}) ; QFile keyFile(QStringLiteral(":/sslcert/client.key")) ; if (!keyFile.open(QIODevice::ReadOnly))        qFatal("Can't open client.key file");
    sslConf.setPrivateKey(QSslKey{keyFile.readAll(), QSsl::Rsa}) ; sslConf.setPeerVerifyMode(QSslSocket::VerifyPeer) ;  webSocket->setSslConfiguration(sslConf) ;#endif

Ensuite, un QRemoteObjectNode est créé, et configuré pour utiliser le WebSocketIoDevice. Il se connecte ensuite à wsserver.

QRemoteObjectNode node;
node.addClientSideConnection(&socket);
node.setHeartbeatInterval(1000);
webSocket->open(QStringLiteral("ws://localhost:8088"));

Un QTreeView est créé pour afficher les données du serveur. Le modèle est acquis à partir du nœud, puis défini comme modèle du QTreeView, qui est ensuite affiché.

QTreeView view;
view.setWindowTitle(QStringLiteral("RemoteView"));
view.resize(640,480);
QScopedPointer<QAbstractItemModelReplica> model(node.acquireModel(QStringLiteral("RemoteModel")));
view.setModel(model.data());
view.show();

return app.exec();

Exemple de projet @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.