a57dbc0252
功能: - 多主机管理 (增删改查, 密码/私钥双认证, 导入导出) - 远程终端 (命令执行 + 常用命令快捷栏 + 超时控制) - SFTP 文件浏览 (上传/下载带进度, 新建/删除/重命名) - 实时监控 (CPU/内存/磁盘/网络, 1-10秒可调刷新) - AI Agent (OpenAI 兼容 API, 5 工具自动调用: 命令/指标/列文件/读文件/上传) 技术栈: PyQt5 + paramiko + psutil + requests + PyInstaller 打包: build_windows.bat / build.sh 一键产出 ~57MB 单文件 exe 测试: core 6/6 + UI 3/3 + E2E 6/6 全部通过
66 lines
1.8 KiB
Python
66 lines
1.8 KiB
Python
"""
|
|
UI 渲染截图:用 QWidget.grab() 把主窗口、各 Tab 渲染成 PNG。
|
|
不开真实显示器,offscreen 平台即可。
|
|
"""
|
|
import os
|
|
import sys
|
|
|
|
os.environ["QT_QPA_PLATFORM"] = "offscreen"
|
|
sys.path.insert(0, os.path.dirname(__file__))
|
|
|
|
from PyQt5.QtWidgets import QApplication
|
|
from PyQt5.QtCore import QTimer, Qt
|
|
from PyQt5.QtGui import QPixmap
|
|
|
|
from ui.main_window import MainWindow
|
|
|
|
|
|
def main():
|
|
out_dir = os.path.join(os.path.dirname(__file__), "screenshots")
|
|
os.makedirs(out_dir, exist_ok=True)
|
|
app = QApplication(sys.argv)
|
|
w = MainWindow()
|
|
w.resize(1280, 800)
|
|
w.show()
|
|
# 等一帧
|
|
QTimer.singleShot(500, lambda: grab_and_quit(w, app, out_dir))
|
|
app.exec_()
|
|
|
|
|
|
def grab_and_quit(w, app, out_dir):
|
|
# 主窗口
|
|
pix = w.grab()
|
|
p = os.path.join(out_dir, "main_window.png")
|
|
pix.save(p, "PNG")
|
|
print(f"[1/4] 主窗口: {p} ({pix.width()}x{pix.height()})")
|
|
|
|
# 各 Tab
|
|
for idx, name in enumerate(["terminal", "files", "monitor", "ai"]):
|
|
w.tabs.setCurrentIndex(idx)
|
|
app.processEvents()
|
|
pix = w.grab()
|
|
p = os.path.join(out_dir, f"tab_{idx}_{name}.png")
|
|
pix.save(p, "PNG")
|
|
print(f"[{idx+2}/5] Tab '{name}': {p}")
|
|
|
|
# 主机对话框
|
|
from ui.host_dialog import HostDialog
|
|
dlg = HostDialog(w, current={"name": "示例", "host": "192.168.1.1", "port": 22,
|
|
"username": "root", "password": "", "key_path": ""})
|
|
dlg.show()
|
|
app.processEvents()
|
|
QTimer.singleShot(200, lambda: finalize(dlg, app, out_dir))
|
|
|
|
|
|
def finalize(dlg, app, out_dir):
|
|
pix = dlg.grab()
|
|
p = os.path.join(out_dir, "host_dialog.png")
|
|
pix.save(p, "PNG")
|
|
print(f"[5/5] HostDialog: {p}")
|
|
dlg.close()
|
|
app.quit()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|