使用python制作MODBUS RTU主站调试工具(一)—— GUI编程
0前言
我实际上并没有用过python进行GUI编程,按照我的C#窗体编程习惯,应该先布置GUI,再对各控件的具体功能进行编程,所以本文就先介绍GUI的python实现。
OS:win10 x64 1909
开发工具:VS Code
Python GUI 库:tkinter
1参考
首先当然是参考现成的modbus调试工具,这里以modscan32为例:
需要参考的地方有两块,一块是连接配置(省去硬件流控制),一块是modbus协议配置。
2控件选择
打开VS Code,首先先创建程序主体:
import tkinter as tk #导入Tkinter模块,Python3环境下首字母t小写
menu = tk.Tk() #创建Tkinter主窗口
menu.title("MODBUS MASTER") #更改窗体标题
... #添加控件
menu.mainloop() #进入主循环
现在要添加控件,结合对modscan32的参考,这个小工具(至少)需要达成的配置内容有:
- 串口编号
- 波特率
- 字长度
- 奇偶校验
- 停止位
- 设备ID
- 从站地址
- 功能码
- 地址显示区显示长度
- 地址显示区
可以看到串口、波特率、字长度、奇偶校验、停止位、功能码都具备下拉框:
但实际上tkinter并没有combobox控件。在tkinter中有三个控件可以实现类似的效果,分别是checkbutton, Radiobutton 和 Listbox ,其中前者更适合二选一的情况,而后两者则适合于多选一的情况,就我个人觉得后两者在功能上并无太大不同,更多在美观性上考虑:
Radiobutton:
var = tk.IntVar()
MPT = [("01 COIL STATUS",1),("02 INPUT STATUS",2),("03 HOLIDING REGISTER",3),("04 INPUT REGISTER",4)]
for mptype, num in MPT:pointtype_list = tk.Radiobutton(text=mptype, variable=var,value=num)pointtype_list.grid()
Tkinter 组件详解(四):Radiobutton
Listbox:
var = tk.StringVar()
var.set(("01 COIL STATUS","02 INPUT STATUS","03 HOLIDING REGISTER","04 INPUT REGISTER"))
pointtype_list = tk.Listbox(listvariable=var,height=4).grid()
注意有多个listbox的时候,选中其中一个控件中的内容后再选择另一个控件,会使之前选中的内容消失,可以通过修改exportselection属性来保持选中:
parity_enter = tk.Listbox(connect_group,listvariable=varp,height=3,exportselection=False) #exportselection=False
————
数据输入框可以使用label控件和搭配entry控件实现;
数据输出框可以使用label控件和搭配text控件实现;
3布局
tkinter共有3种布局方法:pack()、grid()和place():
方法 | 含义 |
---|---|
pack | 按添加顺序排列控件 |
grid | 按行列形式排列控件 |
place | 允许程序员指定控件的大小和位置 |
这里选用grid()方法,最直接的原因是pack()不支持在同一行布置两个控件,这会破坏画面的简洁性:
pack()方法:
deviceid = tk.Label(text = "device id:").pack()
deviceid_enter = tk.Entry().pack()
grid()方法:
deviceid = tk.Label(text = "device id:").grid(row=0,column=0)
deviceid_enter = tk.Entry().grid(row=0,column=1)
grid()方法的基本使用,参考:Tkinter 布局管理器(二):grid
4美观性
4.1组件跨行/列
在使用了grid()方法后,画面布局被分为两列(在本项目中),如果希望控件(如用于表示标题的控件)在两列中位于居中位置,可以使用columnspan实现,其值为所跨的列数:
title = tk.Label(text = "Modbus调试工具",font = 15).grid(row=0,columnspan=2) #columnspan=2 组件跨两列
跨列前:
跨列后:
————
同理可使用rowspan实现跨行。
4.2控件对齐
参考上一张图,label控件默认居中对齐,但在使用习惯中控件一般需要右对齐,在grid()方法中提供了对齐选项:
sticky = “e”/“w”/“s”/"n"
deviceid = tk.Label(config_group,text = "device id:").grid(row=2,column=0,sticky="E") #sticky="E" 右对齐
4.3控件间距调整
在默认情况下控件和控件之间严密贴合,仅留有少量空隙,在视觉上会给人造成一种拥挤感,在grid()中可设置控件间间距:
属性 | 含义 |
---|---|
ipadx | 指定水平方向上的内边距 |
ipady | 指定垂直方向上的内边距 |
padx | 指定水平方向上的外边距 |
pady | 指定垂直方向上的外边距 |
调整前:
start = tk.Button(config_group,text = "开始",width=10).grid(columnspan=2)
调整后:
start = tk.Button(config_group,text = "开始",width=10).grid(columnspan=2,pady=5) #pady=5 按钮组件垂直方向上的外边距为5
4.4控件分区
工具可分为两部分:数据输入域和数据输出域。
可以使用LabelFrame将数据输入域包裹起来:
config_group = tk.LabelFrame(text="设置栏") #边框注释
config_group.grid(row=1,columnspan=2,padx=10, pady=10)
LabelFrame是一种容器,可以存放各类控件,如果希望将指定控件移入容器内,需要修改该控件的父容器:
deviceid = tk.Label(config_group,text = "device id:").grid(row=2,column=0,sticky="E")#label组件位于LabelFrame(config_group)容器中
5样品展示
后续加入功能后GUI肯定会修改的。
附录 获取控件输入值/令控件输出值
如何获取在entry()、listbox()和radiobutton()控件中输入的值,并通过text()输出?
这里设计了一个小程序进行演示:
import tkinter as tk
window=tk.Tk()#创建entry控件
e=tk.Entry(window)
e.pack()#创建listbox控件
varw = tk.StringVar()
varw.set(("7","8"))
wlength_enter = tk.Listbox(listvariable=varw,height=2,exportselection=False)
wlength_enter.pack()#创建radiobutton控件
var = tk.IntVar()
MPT = [("01 COIL STATUS",1),("02 INPUT STATUS",2),("03 HOLIDING REGISTER",3),("04 INPUT REGISTER",4)]
for mptype, num in MPT:pointtype_list = tk.Radiobutton(text=mptype, variable=var,value=num)pointtype_list.pack()################核心代码##################
#获取控件值通过text控件输出
def entry_enter():var1=e.get() #获取控件输入值 t.insert('insert',var1)
def listbox_enter():var1 = wlength_enter.get(wlength_enter.curselection()) #获取控件输入值 t.insert('insert',var1)
def radiobutton_enter():var1 = var.get() #获取控件输入值 t.insert('insert',var1)# 创建button控件
b1=tk.Button(window,text='entry',width=15,height=2,command=entry_enter)
b1.pack()
b2=tk.Button(window,text='listbox',width=15,height=2,command=listbox_enter)
b2.pack()
b3=tk.Button(window,text='radiobutton',width=15,height=2,command=radiobutton_enter)
b3.pack()#创建text控件
t=tk.Text(window,height=2)
t.pack()window.mainloop()
画面中布置了3个按钮,按动不同的按钮,会将不同控件中的输入值输出到text中,这样设置的原因是程序似乎不支持实时输出 输入值,所以需要通过这种方法手动执行。
使用python制作MODBUS RTU主站调试工具(一)—— GUI编程相关推荐
- 使用python制作MODBUS RTU主站调试工具(二)—— modbus_tk配置
本文是使用python制作MODBUS RTU主站调试工具(一)-- GUI编程 的后续. OS:win10 x64 1909 开发工具:VS Code Python 库:modbus_tk/seri ...
- 树莓派 rfid_树莓派工控机做Modbus RTU主站读取RFID数据
KUNBUS Revpi Core 3是工业级的树莓派,可作为小型的工业PC用,外观十分小巧,操作简单,DIN导轨模块化安装,RevPi core 3能与RevPi IO连接,能实时对这些IO的控制. ...
- Modbus协议栈应用实例之一:Modbus RTU主站应用
自从开源了我们自己开发的Modbus协议栈之后,有很多朋友建议我针对性的做几个示例.所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例,在这一篇中我们先来使用协议栈实现Modbu ...
- 软件设计开发笔记3:基于QT的Modbus RTU主站
Modbus是一种常见的工业系统通讯协议.在我们的设计开发工作中经常使用到它.在这一篇中我们将简单实现一个基于QT的Modbus RTU主站上位工具. 1.概述 Modbus RTU主站应用很 ...
- python制作软件界面_Python图形界面GUI程序设计
1.GUI是什么? 图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面. 图形用户界面是一种人与计算机通信的界面显 ...
- 用python做tkinter_Python下用Tkinter进行GUI编程
Python可用的GUI编程的包很多,Tkinter也是其中一个半标准的工具包. 作为一个老牌的Python GUI工具包(皮皮书屋里找了本书,竟然是2001年的),它由Tk GUI包装而来.在Win ...
- MCGS作为Modbus RTU主站
目录 1. 所需软件 2. 配置过程 2.1 MCGS组态 2.2 Modbus Slave配置 2.3 虚拟串口驱动配置 3. 试验结果 1. 所需软件 MCGS组态软件.MCGS模拟环境.Mod ...
- python制作图形化小游戏_创意编程|Python的GUI简易界面设计测测你的反应力
Python的GUI简易界面设计案例 测测你的反应力 作为初次接触代码编程的你,是不是觉得Python程序除了"码"就是"字"即使是有趣的程序除了烧烧 ...
- 2000页Python系列PPT分享九:(GUI编程)(122页)
总体说明:本套PPT共约2000页,包含董付国老师Python系列图书<Python程序设计基础(第2版)>(2018年8月第4次印刷).<Python程序设计(第2版)>(2 ...
最新文章
- ActiveMQ — 单节点 — 安装与配置
- 自制MVC之工具类插件一
- python ssl模块用法详解_一看就懂,Python 日志模块详解及应用!
- linux grep 正则表达式
- python接口自动化测试面试题_Python接口自动化面试题总结
- matlab循环读取变量,Matlab for 多个变量循环能不能这样啊 ,求教高手!!!!
- 自由软件之父回归 FSF,遭 1933 人、21 家组织联名抵制!
- Netflix:如何打造开放协作的实时 ETL 平台?
- WifiConfigManager NetworkSelector 和 WifiConnectivityManager
- Eclipse主题插件:Eclipse Color Theme
- Verilog算法入门
- 一个20岁工作了4年男网管真情自白书
- hdu-5064(dp)
- dnf单机版 不显示服务器,dnf单机云服务器
- iframe 跳转到其他页面
- 游戏开发bug解决思路
- 古代帝王有哪些“恩爱夫妻”?
- JAVA名字正则表达式(包含新疆姓名)
- 吃饭 睡觉 打豆豆!!!
- amd显卡多屏识别了 但是屏幕不亮_最近发布:针对AMD显卡多屏显示设置的完整解决方案。ppt28...