import QtQuick import QtQuick.Controls import QtQuick.Layouts import Xpl2 ApplicationWindow { id: root width: 800 height: 600 visible: true title: "XPL2 Demo" Connections { target: Xpl2Client function onConnectedChanged() { log(Xpl2Client.connected ? "Connected" : "Disconnected"); } function onResponseReceived(response: string) { log("← " + response); responseModel.append({ text: response }); } function onErrorOccurred(error: string) { log("ERROR: " + error); } function onStatusMessage(message: string) { log(message); } } function log(msg: string) { let ts = new Date().toLocaleTimeString(Qt.locale(), "HH:mm:ss.zzz"); logModel.append({ text: "[" + ts + "] " + msg }); logView.positionViewAtEnd(); } ColumnLayout { anchors.fill: parent anchors.margins: 16 spacing: 12 // --- Connection --- GroupBox { title: "Connection" Layout.fillWidth: true GridLayout { columns: 4 anchors.fill: parent Label { text: "Host:" } TextField { id: hostField text: Xpl2Client.host Layout.fillWidth: true onEditingFinished: Xpl2Client.host = text } Label { text: "Port:" } TextField { id: portField text: Xpl2Client.port implicitWidth: 80 validator: IntValidator { bottom: 1 top: 65535 } onEditingFinished: Xpl2Client.port = parseInt(text) } Button { text: Xpl2Client.connected ? "Disconnect" : "Connect" Layout.columnSpan: 4 Layout.alignment: Qt.AlignRight onClicked: { if (Xpl2Client.connected) Xpl2Client.disconnectFromServer(); else Xpl2Client.connectToServer(); } } } } // --- Send Command --- GroupBox { title: "Command" Layout.fillWidth: true enabled: Xpl2Client.connected RowLayout { anchors.fill: parent TextField { id: cmdField placeholderText: "Enter command…" Layout.fillWidth: true onAccepted: sendBtn.clicked() } Button { id: sendBtn text: "Send" onClicked: { if (cmdField.text.length > 0) { Xpl2Client.sendCommand(cmdField.text); cmdField.text = ""; } } } } } // --- Responses --- GroupBox { title: "Responses" Layout.fillWidth: true Layout.fillHeight: true ListView { id: responseView anchors.fill: parent clip: true model: ListModel { id: responseModel } delegate: Text { required property string text width: responseView.width wrapMode: Text.Wrap font.family: "monospace" font.pixelSize: 13 text: model.text } } } // --- Debug Log --- GroupBox { title: "Log" Layout.fillWidth: true Layout.preferredHeight: 160 ListView { id: logView anchors.fill: parent clip: true model: ListModel { id: logModel } delegate: Text { required property string text width: logView.width wrapMode: Text.Wrap font.family: "monospace" font.pixelSize: 12 color: "#555" text: model.text } } } } }