Warning
This section contains snippets that were automatically translated from C++ to Python and may contain errors.
QtRemoteObjects WebSockets Applications#
Using a non-QIODevice-based transport (QWebSocket) with QtRemoteObjects .
This example shares a QStandardItemModel
over a web socket. The model can be edited in the window of the wsserver
application, and the changes are propagated to the window of the wsclient
application.
This is made possible by implementing a small QIODevice-derived wrapper, WebSocketIoDevice
, for QWebSocket
. SSL is used if Qt is compiled with support for it.
The WsServer Application#
The wsserver
application creates a QStandardItemModel
with two columns and inserts data into it.
if __name__ == "__main__": QLoggingCategory.setFilterRules("qt.remoteobjects.debug=False\n" "qt.remoteobjects.warning=False") app = QApplication([]) modelSize = 100000 list = QStringList() sourceModel = QStandardItemModel() hHeaderList = QStringList() hHeaderList << "First Column with spacing" << "Second Column with spacing" sourceModel.setHorizontalHeaderLabels(hHeaderList) list.reserve(modelSize) for i in range(0, modelSize): firstItem = QStandardItem("FancyTextNumber %1".arg(i)) if i == 0: firstItem.appendRow(addChild(2, 2)) secondItem = QStandardItem("FancyRow2TextNumber %1".arg(i)) if i % 2 == 0: firstItem.setBackground(Qt.red) row = QList() row << firstItem << secondItem sourceModel.invisibleRootItem().appendRow(row) #sourceModel.appendRow(row) list << "FancyTextNumber %1".arg(i)
It then starts a QWebSocketServer
bound to port 8088, and hosts the data model.
QWebSocketServer webSockServer{"WS QtRO", QWebSocketServer.NonSecureMode} webSockServer.listen(QHostAddress.Any, 8088) hostNode = QRemoteObjectHost() hostNode.setHostUrl(webSockServer.serverAddress().toString(), QRemoteObjectHost.AllowExternalRegistration) hostNode.enableRemoting(sourceModel, "RemoteModel", roles)
When handling new connections, SSL is configured if Qt is compiled with support for it. Then a WebSocketIoDevice
is created using the incoming WebSocketServer connection.
webSockServer.newConnection.connect(&hostNode, [&hostNode, &webSockServer]{ while auto conn = webSockServer.nextPendingConnection(): #ifndef QT_NO_SSL # Always use secure connections when available sslConf = QSslConfiguration() certFile = QFile(":/sslcert/server.crt") if not certFile.open(QIODevice.ReadOnly): qFatal("Can't open client.crt file") sslConf.setLocalCertificate(QSslCertificate{certFile.readAll()}) keyFile = QFile(":/sslcert/server.key") if not 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) conn.sslErrors.connect(conn.deleteLater) #endif conn.disconnected.connect(conn.deleteLater) conn.errorOccurred.connect(conn.deleteLater) ioDevice = WebSocketIoDevice(conn) conn.destroyed.connect(ioDevice.deleteLater) hostNode.addHostSideConnection(ioDevice) })
A QTreeView is created with the QStandardItemModel as model. Then multiple timers are started with QTimer::singleShot to perform more modifications to the model.
view = QTreeView() view.setWindowTitle("SourceView") view.setModel(sourceModel) view.show() handler = TimerHandler() handler.model = sourceModel QTimer::singleShot(5000, handler.changeData) QTimer::singleShot(10000, handler.insertData) QTimer::singleShot(11000, handler.changeFlags) QTimer::singleShot(12000, handler.removeData) QTimer::singleShot(13000, handler.moveData) sys.exit(app.exec())
The WsClient Application#
The wsclient
application creates a QWebSocket and a WebSocketIoDevice
taking it as an argument.
QScopedPointer<QWebSocket> webSocket{QWebSocket()} socket = WebSocketIoDevice(webSocket.data())
If Qt is compiled with support for SSL, the client is configured with it.
#ifndef QT_NO_SSL # Always use secure connections when available sslConf = QSslConfiguration() certFile = QFile(":/sslcert/client.crt") if not certFile.open(QIODevice.ReadOnly): qFatal("Can't open client.crt file") sslConf.setLocalCertificate(QSslCertificate{certFile.readAll()}) keyFile = QFile(":/sslcert/client.key") if not 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
Then a QRemoteObjectNode
is created, and setup to use the WebSocketIoDevice. Then it connects to wsserver
.
node = QRemoteObjectNode() node.addClientSideConnection(socket) node.setHeartbeatInterval(1000) webSocket.open("ws://localhost:8088")
A QTreeView is created to display the data from the server. The model is acquired from the node, and it is then set as the model of the QTreeView, which is then shown.
view = QTreeView() view.setWindowTitle("RemoteView") view.resize(640,480) model = QScopedPointer(node.acquireModel("RemoteModel")) view.setModel(model.data()) view.show() sys.exit(app.exec())