comtool 优雅 好用的 串口助手 ,开源 无广告 跨平台(linux windows mac) (write by python) linux 带图形界面 |
您所在的位置:网站首页 › macos串口调试工具 › comtool 优雅 好用的 串口助手 ,开源 无广告 跨平台(linux windows mac) (write by python) linux 带图形界面 |
好看实用的跨平台的无广告带图形界面的串口调试助手,网络调试助手,终端工具,波形显示工具等, COMTool
版权声明:本文为 neucrack 的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接(持续更新):https://neucrack.com/p/186
所有代码均开源!喜欢请点个 star 哦~: Github 跨平台(windows,linux,macOS,Raspberry Pi)串口调试助手/网络调试助手/终端工具/波形实时显示工具,完全开源! 可以直接下载使用,也可以自己根据需求二次开发,可以直接添加插件,省去了自己去调试数据收发和打包的麻烦,基于此很快就能编写出一个能够稳定实用的 GUI 程序, 编写插件十分简单,只需要实现几个函数即可。 Windows Linux Raspberry Pi macOS![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 图中不一定是最新版本,最新版本请到github 以查看最新版本 特性 跨平台 (Windows, Linux, macOS, Raspberry Pi)(使用 python 编写,只要你的平台支持 python) 可靠,界面不会卡死 多语言支持 白色主题和黑色主题切换 多种字符编码格式支持,比如 ASII,GBK(Chinese),UTF-8,UTF-16 等 自动保存设置(退出保存) 多种连接方式支持,同时支持编写连接插件 串口 支持 串口自动检测,支持记住上次使用的串口号 串口断线自动重连 波特率(随意设置)、校验、停止位、流控等设置支持 rts 和 dtr 手动控制 TCP/UDP 支持,包括客户端和服务端模式支持 SSH 客户端支持 插件支持(插件开发请看docs/plugins_zh.md)),内置插件如下: 调试插件,基本收发数据调试 基础收发功能(字符(ASCII) 和 十六进制(HEX)) 收发计数 清空接收缓冲区支持 自动换行 定时发送 发送记录保存和再次选中发送 自定义常用发送内容,一键发送 两种常用换行符CR LF(\r\n) 和 LF(\n) 支持 快捷键比如 Ctrl+Enter 发送数据 转义字符支持,比如 \r \n \t \x 等 收发记录,以及添加时间戳和记录到文件功能 发送文件 unix 终端风格颜色支持,比如\x1b[33;42mhello\x1b[0mhello2 协议插件,可自定义收发协议 自定义协议编解码支持 自定义快捷键发送 终端插件, 基本终端功能 图表插件 支持动态添加图表控件,添加你需要的控件 实时显示折线图,支持自定义协议头(支持转移符) 自定义按钮来发送数据,支持自定义快捷键 下载 github release 页面百度云 提取码: 7ip6 源码简单介绍使用了Python3编写, 界面使用PyQt5编写,国际化(多语言)使用 babel处理,Main.py中包含了主要逻辑,布局使用了qss(一种类似css的语法,支持一些css2语法,实际用起来还是有点诡异= =)。 这个项目是自己刚学 python 的时候拿来练手的,2017年做了串口助手的功能并发布, 后面断断续续一直在维护,支持了更多功能, 以及支持了插件 源码运行的方法以及插件开发方法在项目首页的 README 文件中有详细说明,仔细阅读即可 如果你打算修改源码或者写插件,请一定要注意: 变量风格和 PyQt的一样了,变量函数小驼峰,类大驼峰所有更新和获取 UI 控件的操作都需要在主线程里面完成,比如初始化,或者槽里面更新如果你有代码需要长时间占用 CPU, 比如 sleep, 或者等待什么或者消耗时长长的操作比如串口发送大文件这样的操作,请开一个新的线程进行处理,不要在主线程或者槽里面处理如果你在你的新线程里面要获取 UI 控件的值, 请给 UI 控件绑定变量, 代码里面是绑定到了self.config的值,当UI 控件改变,去改变这个变量,其它线程就能直接获取这个变量,由于 Python 的多线程并不是真正的多线程, 线程锁也不需要如果你在你的新线程要去改变控件,请新建一个信号,信号绑定一个槽,新的线程里面需要改变控件时发送信号,在槽函数里面去改变 UI 控件 插件开发参考文档: https://github.com/Neutree/COMTool/blob/master/docs/plugins_zh.md 参考例程: myplugin.py 和 myplugin2 比如 myplugin.py 如下(实际以源码中的文件内容为准,可能有小幅度改动,但是改动不会很大) 定义一个 Plugin类,名字固定, 集成自Plugin_Base类,实现几个必要的方法即可,以下对代码加了中文解释说明: ''' @brief This is an example plugin, can receive and send data @author @date @license LGPL-3.0'''# 导入画界面需要用到的库(PyQt5)from PyQt5.QtWidgets import QWidget, QVBoxLayout, QTextEdit, QPushButton, QLineEditfrom PyQt5.QtCore import pyqtSignalfrom PyQt5.QtGui import QFont, QTextCursortry: # 导入需要使用到的类,直接使用了相对路径,优先从当前路径下找,这样在用源码调试时就会调用这个了 from plugins.base import Plugin_Base from conn import ConnectionStatus from i18n import _except ImportError: # 如果上面的相对路径找不到再去 python 库里面找 COMTool 包调用 from COMTool.plugins.base import Plugin_Base from COMTool.i18n import _ from COMTool.conn import ConnectionStatus# 定义一个固定名字为 Plugin 的类, 继承子 Plugin_Baseclass Plugin(Plugin_Base): # 定义插件的唯一 id id = "myplugin" # 定义插件的名称,这里用了英文,如果插件需要支持国际化,请参考 myplugin2 示例 name = "my plugin" # 用于通知 UI 线程更新 UI 的信号,写 pyqt 程序时需要非常注意所有 UI 更新只能在 UI 线程里,否则界面可能会被阻塞而表现为卡死 updateSignal = pyqtSignal(str, str) def onConnChanged(self, status:ConnectionStatus, msg:str): # 连接状态改变回调函数 print("-- connection changed: {}, msg: {}".format(status, msg)) def onWidgetMain(self, parent): ''' 生成主界面, 需要返回一个 QWidget 对象,在这个 QWidget 对象中可以画任何你想实现的界面 包括在这里加载 ui 文件都是可以的 此处样例顶一个两个输入框,一个用来显示接收到的数据,一个用来输入需要发送的信息, 然后定义一个按钮,按钮用来发送消息 ''' # 定义一个主控件 self.widget = QWidget() # 定义布局 layout = QVBoxLayout() # 定义接收框 self.receiveArea = QTextEdit("") font = QFont('Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace, Microsoft YaHei', 10) self.receiveArea.setFont(font) self.receiveArea.setLineWrapMode(QTextEdit.NoWrap) # 定义发送框 self.input = QTextEdit() self.input.setAcceptRichText(False) # 定义发送按钮,同样的,这里的文字可以国际化,参考 myplugin2 的做法 self.button = QPushButton("Send") # 添加控件到布局中 layout.addWidget(self.receiveArea) layout.addWidget(self.input) layout.addWidget(self.button) self.widget.setLayout(layout) # 添加事件绑定 ,按钮按下触发函数,触发的函数会在 UI 线程中运行 self.button.clicked.connect(self.buttonSend) # 添加 UI 更新事件回调函数绑定 self.updateSignal.connect(self.updateUI) # 返回主控件 return self.widget def buttonSend(self): ''' 按钮绑定的事件函数, 运行在 UI 线程 ''' # 获取数据 data = self.input.toPlainText() # 没有数据,提示需要输入,同样这里的文字也需要国际化,参照 myplugin2 if not data: # to pop up a warning window self.hintSignal.emit("error", "Error", "Input data first please") return # 将字符串编码为字节,编码方式使用了全局编码设定,即界面上的下拉框选项 dataBytes = data.encode(self.configGlobal["encoding"]) # 调用发送,这个函数已经自动被绑定到了对应的连接上 self.send(dataBytes) def updateUI(self, dataType, data): ''' 更新 UI, 运行在 UI 线程 ''' if dataType == "receive": # 将光标移动到最底并插入数据 self.receiveArea.moveCursor(QTextCursor.End) self.receiveArea.insertPlainText(data) def onReceived(self, data : bytes): ''' 接收到数据的回调函数, 注意此函数不在 UI 线程,是一个独立的接收线程, 所以如果有时间消耗长的代码需要执行可以放到这里执行,执行完毕需要显示内容再提交给 UI 线程 ''' # 调用基类的接收函数 super().onReceived(data) # 解码数据,这里就是将字节数据解码为字符串 dataStr = data.decode(self.configGlobal["encoding"]) # 将内容提交给 UI 线程进行显示 # 注意不能直接在这里调用 seld.receiveBox, 否则可能会出现程序退出或者界面无响应等问题 # 通过我们定义的 UI 更新信号将需要更新的内容传达给 UI 线程即可 self.updateSignal.emit("receive", dataStr)编写完毕后,通过界面的加载插件按钮即可加载插件;另外如果想把插件集成到软件中,在 这里 添加一下插件的类就好了;也可以将插件打包成 python 包,包名需要comtool_plugin_xxx格式, 用 pip安装到系统,comtool(仅限源码安装) 就会自动扫描到 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |