import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 import DelegateUI 1.0 import "../MyGlobals" 1.0 import SSHManager 1.0 Item { visible: true // SSH控制台输出显示区域 Item { id:consolearea anchors { fill: parent margins: 10 bottomMargin: 46 } ScrollView { id: scrollView anchors.fill: parent clip: true TextArea { id: consoleOutput selectByMouse: true textFormat: Text.RichText readOnly: true wrapMode: Text.WrapAnywhere font { pixelSize: 14 family: DelTheme.Primary.fontPrimaryFamily } color: DelTheme.Primary.colorTextBase background: Rectangle { color: DelTheme.isDark ? "#2d2d2d" : "#f5f5f5" radius: 4 } // 自动滚动到底部 onTextChanged: { if (length > 0) { cursorPosition = length } } } } } DelInput { id: inputField width: consolearea.width iconPosition: DelInput.Position_Left iconSource: DelIcon.ForwardOutlined placeholderText: qsTr("这里可以输入服务器命令") anchors { top: consolearea.bottom topMargin: 6 horizontalCenter: parent.horizontalCenter } // 添加回车键事件 onAccepted: { SSHManager.sendInput(text) text = "" } // 监听 Ctrl+C Keys.onPressed: (event) => { if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_C) { SSHManager.sendInput("\x03") } } } // ANSI转HTML的转换逻辑 function ansiToHtml(text) { // 第一步:处理颜色代码 let colored = text.replace(/\x1B\[([0-9;]*)m/g, function(match, codes) { let styles = []; for (let code of codes.split(';')) { switch (parseInt(code)) { case 0: return ""; case 1: styles.push("font-weight:bold"); break; case 3: styles.push("font-style:italic"); break; case 4: styles.push("text-decoration:underline"); break; case 30: styles.push("color:black"); break; case 31: styles.push("color:red"); break; case 32: styles.push("color:green"); break; case 33: styles.push("color:yellow"); break; case 34: styles.push("color:blue"); break; case 35: styles.push("color:magenta"); break; case 36: styles.push("color:cyan"); break; case 37: styles.push("color:white"); break; case 40: styles.push("background-color:black"); break; // 其他颜色代码... } } return styles.length ? `` : ""; }); // 第二步:清除所有 ANSI 转义序列(包括 XTerm 标题、控制序列等) let cleaned = colored //删除 XTerm 窗口标题序列(格式:\x1B]0;标题\x07 或 \x1B]0;标题\x1B\) .replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, '') //删除其他 ANSI 控制序列(包括以 ? 开头的模式设置,如 ?1034h) .replace(/\x1B\[[1034h;?]*[A-Za-z]/g, ''); return cleaned; } function connectionSuccess(){ } function connectionFailed(error){ consoleOutput.text += "连接服务器失败" + error + "\n" } function disconnected(){ consoleOutput.text += "服务器断开连接\n" } function updateStatus(msg) { consoleOutput.text += (msg + "\n") } function appendOutput(msg) { // 转义 HTML 特殊字符 const safeMsg = msg.replace(//g, ">").replace(/\n/g, "
"); // 新增换行符转换 const zemsg = ansiToHtml("> " + safeMsg) consoleOutput.text += zemsg; } // 初始化后自动连接示例(可选) Component.onCompleted: { SSHManager.connectionSuccess.connect(connectionSuccess) SSHManager.connectionFailed.connect(connectionFailed) SSHManager.statusMessage.connect(updateStatus) SSHManager.disconnected.connect(disconnected) SSHManager.shellOutput.connect(appendOutput) consoleOutput.text = "控制台已就绪...\n" } // 窗口关闭时自动触发清理 Component.onDestruction: { // 断开所有信号连接 SSHManager.connectionSuccess.disconnect(connectionSuccess); SSHManager.connectionFailed.disconnect(connectionFailed); SSHManager.statusMessage.disconnect(updateStatus); SSHManager.disconnected.disconnect(disconnected); SSHManager.shellOutput.disconnect(appendOutput); console.log("窗口关闭,已断开所有信号连接并清理资源。"); } }