QtRemoteObjects による WebSockets アプリケーション
QtRemoteObjects でQIODevice ベースではないトランスポート(QWebSocket)を使用する。
この例では、WebSocketを介してQStandardItemModel を共有します。wsserver アプリケーションのウィンドウでモデルを編集すると、その変更内容がwsclient アプリケーションのウィンドウに反映されます。
これは、QWebSocket 向けにQIODevice を継承した小さなラッパーであるWebSocketIoDevice を実装することで実現されています。Qt が SSL サポート付きでコンパイルされている場合は、SSL が使用されます。

WsServer アプリケーション
wsserver アプリケーションは、2つの列を持つQStandardItemModel を作成し、そこにデータを挿入します。
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);
}その後、ポート 8088 にバインドされた `QWebSocketServer ` を起動し、データモデルをホストします。
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);新しい接続を処理する際、QtがSSL対応でコンパイルされている場合は、SSLが設定されます。その後、着信したWebSocketServer接続を使用してWebSocketIoDevice が作成されます。
QObject::connect(&webSockServer,&QWebSocketServer::newConnection, &hostNode, [&hostNode, &webSockServer]{
while(autoconn=webSockServer.nextPendingConnection()) {
#ifndef QT_NO_SSL
// 利用可能な場合は常にセキュアな接続を使用する
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);
autoioDevice= newWebSocketIoDevice(conn);
QObject::connect(conn,&QWebSocket::destroyed,ioDevice, &WebSocketIoDevice::deleteLater);
hostNode.addHostSideConnection(ioDevice);
}
});QStandardItemModel をモデルとして QTreeView が作成されます。その後、QTimer::singleShot を使用して複数のタイマーが起動され、モデルに対してさらなる変更が行われます。
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();WsClient アプリケーション
wsclient アプリケーションは、引数として受け取ったWebSocketIoDevice を使用して、QWebSocketと を作成します。
QScopedPointer<QWebSocket> webSocket{new QWebSocket};
WebSocketIoDevice socket(webSocket.data());QtがSSLをサポートするようにコンパイルされている場合、クライアントはSSLを使用するように設定されます。
#ifndef QT_NO_SSL
// 利用可能な場合は常にセキュアな接続を使用する
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次に、QRemoteObjectNode が作成され、WebSocketIoDeviceを使用するように設定されます。その後、wsserver に接続します。
QRemoteObjectNode node;
node.addClientSideConnection(&socket);
node.setHeartbeatInterval(1000);
webSocket->open(QStringLiteral("ws://localhost:8088"));サーバーからのデータを表示するために、QTreeViewが作成されます。ノードからモデルを取得し、それをQTreeViewのモデルとして設定した後、QTreeViewを表示します。
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();© 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.