采用客户端-服务器架构: 将计算密集型任务(推理、数据库操作、图像捕获)放在服务器端,客户端专注于提供用户交互界面和数据展示。降低客户端的硬件要求,便于集中管理模型和数据。
混合网络通信协议:WebSocket: 用于实时的控制指令(JSON文本)、状态信息(JSON文本)和标注后图像帧(二进制数据)的推送。提供低延迟、双向的持久连接。
HTTP: 用于文件上传(模型、视频)。HTTP的请求-响应模型更适合处理文件这种一次性、可能较大的数据传输。
客户端使用Qt的多线程和信号槽机制:将WebSocket连接和Asyncio事件循环放在一个独立的QThread中运行,确保主线程的UI不被阻塞。使用QRunnable和QThreadPool处理HTTP文件上传任务,避免在主线程中执行耗时的文件读写和网络请求。利用Qt的信号与槽机制实现跨线程的安全通信,如后台线程通过信号发送接收到的数据或状态变化,主线程的槽函数响应并更新UI。pyqtSignal在Asyncio线程中使用asyncio.run_coroutine_threadsafe来发射,确保安全。
服务器端使用Asyncio构建高并发网络服务:利用Asyncio的协程优势,异步处理多个客户端的WebSocket连接和消息,提高服务器的并发能力。推理循环(run_inference_loop)作为一个独立的Asyncio任务运行,与其他网络任务并发执行。HTTP服务器运行在一个单独的Python线程中,避免阻塞Asyncio事件循环。统一输入源管理: 在服务器端抽象出"输入源"的概念,可以是一个摄像头索引或一个视频文件路径。客户端通过统一的UI(一个下拉框)选择输入源,并通过WebSocket发送请求给服务器,服务器负责实际打开并从该源捕获画面。
模块化设计: 将项目代码分为不同的模块(common, network, view),每个模块负责特定的功能,提高代码的可维护性和可读性。例如,client.py只负责网络通信逻辑,main_window.py只负责UI的创建和信号连接。
增强错误报告和日志记录: 集成标准Python logging库,通过自定义的QtLogHandler将日志输出到GUI界面的日志窗口,同时记录到文件。使用InfoBar在UI上及时给用户反馈操作结果或错误信息。