En esta página

QtRemoteObjects Aplicaciones WebSockets

Usando un transporte no basado enQIODevice(QWebSocket) con QtRemoteObjects.

Este ejemplo comparte un QStandardItemModel a través de un web socket. El modelo puede editarse en la ventana de la aplicación wsserver, y los cambios se propagan a la ventana de la aplicación wsclient.

Esto es posible implementando una pequeña envoltura derivada de QIODevice, WebSocketIoDevice, para QWebSocket. SSL se utiliza si Qt se compila con soporte para ello.

Ventana SourceView con tabla de dos columnas y resaltado de filas en color

La aplicación WsServer

La aplicación wsserver crea un QStandardItemModel con dos columnas e inserta datos en él.

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);
    }

A continuación, inicia un QWebSocketServer enlazado al puerto 8088, y aloja el modelo de datos.

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);

Cuando se manejan nuevas conexiones, se configura SSL si Qt está compilado con soporte para ello. Entonces se crea un WebSocketIoDevice usando la conexión WebSocketServer entrante.

    QObject::connect(&webSockServer, &QWebSocketServer::newConnection, &hostNode, [&hostNode, &webSockServer]{ while(auto conn = webSockServer.nextPendingConnection()) {#ifndef QT_NO_SSL // Usar siempre conexiones seguras cuando estén 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); } });

Se crea un QTreeView con el QStandardItemModel como modelo. Luego se inician múltiples temporizadores con QTimer::singleShot para realizar más modificaciones al modelo.

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();

La Aplicación WsClient

La aplicación wsclient crea un QWebSocket y un WebSocketIoDevice tomándolo como argumento.

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

Si Qt se compila con soporte para SSL, el cliente se configura con él.

#ifndef QT_NO_SSL // Usar siempre conexiones seguras cuando estén 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

Entonces se crea un QRemoteObjectNode, y se configura para usar el WebSocketIoDevice. Luego se conecta a wsserver.

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

Se crea un QTreeView para mostrar los datos del servidor. El modelo se adquiere del nodo, y luego se establece como el modelo del QTreeView, que luego se muestra.

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();

Proyecto de ejemplo @ 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.