# -*- coding: utf-8 -*-
"""
#导入库
import tkinter as tk
import os
import time
import serial.tools.list_ports
import threading
def Selection():
pass
def Savefile(dd):
OutputText.delete(1.0,tk.END)
OutputText.insert(tk.END, dd)
filepath = filePath.get()
filename = time.strftime("%Y-%m-%d", time.localtime())
wholename = os.path.join(filepath, filename) #完整的路径+文件名(无后缀)
if os.path.exists(filepath) == False:
os.mkdir(filepath)
with open(wholename+'.txt', 'a') as f1:
ls = dd +' '+ time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) +'\n'#\t表示4个空格
f1.writelines(ls)
def Readser1():
#global data1 作为参数传给savefile函数,savefile函数不调用data1了,所以不用声明全局变量了
while t1_flag:
try:
data1=ser1.readline()#readall如果sleep时间太短可能会发生数据截断,使用readline按行读取用初始化的timeout控制读取时限
#ser1.flushInput()缓冲区清理基本用不上
data1 = data1.decode('ASCII')
if len(data1)>0:
Savefile(data1.rstrip())
ddaa=[]
data=data1.split(' ')
for i in data:
if len(i)>0:
ddaa.append(i)
labelyali1.configure(text=ddaa[len(ddaa)-3])#原始数据后边空格接了回车符,多了一个len数,所以减去2和3
labeljieguo1.configure(text=ddaa[len(ddaa)-2])
time.sleep(0.5)
except Exception as e:
print("错误: ", e)
def Readser2():
#global data2
while t2_flag:
try:
data2=ser2.readline()
#ser2.flushInput()
data2 = data2.decode('ASCII')
if len(data2)>0:
Savefile(data2.rstrip())
ddaa=[]
data=data2.split(' ')
for i in data:
if len(i)>0:
ddaa.append(i)
labelyali2.configure(text=ddaa[len(ddaa)-3])
labeljieguo2.configure(text=ddaa[len(ddaa)-2])
time.sleep(0.5)
except Exception as e:
print("错误: ", e)
def Start():
global t1_flag
t1_flag=True
global t2_flag
t2_flag=True
l1.config(state='disable')
l2.config(state='disable')
l3.config(state='disable')
btnStop['state']= 'normal'
btnStart['state'] = 'disabled'
entryfilePath.configure(state = 'disabled')
Serlist()
if plcflag.get() == 1:
print('plc')
if serflag_1.get() == 1:#串口初始化并启动串口线程
try:#防止串口报错退出主程序,使用try结构忽略报错
ser1.port = 'COM12' #端口号
ser1.baudrate = 9600 #波特率
ser1.bytesize=serial.EIGHTBITS
ser1.timeout = 3 #超时设置,1s未读取到数据则返回结果
ser1.stopbits=serial.STOPBITS_ONE#1停止位
ser1.parity=serial.PARITY_NONE#无校验
ser1.open() #打开串口
except Exception as e:
print("错误: ", e)
t1=threading.Thread(target=Readser1)#线程指向readser1
t1.start()
if serflag_2.get() == 1:
try:
ser2.port = 'COM12' #端口号
ser2.baudrate = 9600 #波特率
ser2.bytesize=serial.EIGHTBITS
ser2.timeout = 3 #超时设置,1s未读取到数据则返回结果
ser2.stopbits=serial.STOPBITS_ONE#1停止位
ser2.parity=serial.PARITY_NONE#无校验
ser2.open() #打开串口
except Exception as e:
print("错误: ", e)
t2=threading.Thread(target=Readser2)
t2.start()
def Stop():
global t1_flag
global t2_flag
l1.config(state='normal')
l2.config(state='normal')
l3.config(state='normal')
btnStop['state'] ='disabled'
btnStart['state'] = 'normal'
if serflag_1.get() == 1:
t1_flag=False
if ser1.is_open:
ser1.close()
if serflag_2.get() == 1:
t2_flag=False
if ser2.is_open:
ser2.close()
print('lllllllllllllllllllllllllllllllllllllll')
def Serlist():
port_list = list(serial.tools.list_ports.comports())
port_serial = []
#*******提取COM口的端口号*******
if len(port_list) <= 0:
RunInf.set("未找到端口!")
else:
for i in range(len(port_list)):
port_serial.append(list(port_list[i])[0])
RunInf.set(port_serial)
#btnStart['state'] = 'normal'
def Showtime():
while time_flag:
tt=time.strftime("%Y-%m-%d \n %H:%M:%S", time.localtime())
labeltime.configure(text=tt)
if btnStop['state'] == 'disabled':
if plcflag.get() == 0 and serflag_1.get() == 0 and serflag_2.get() == 0:
btnStart['state'] = 'disabled'
else:
btnStart['state'] = 'normal'
time.sleep(0.2)
window = tk.Tk()#窗体变量定义
window.title('试漏工控机')#定义窗体名称
window.geometry('900x600')#定义主窗体尺寸
l = tk.Label(window, width=15,bg='red',text='实验室',font = ('楷体', 20))
l.place(x=400,y=0,width=200,heigh=40)
plcflag = tk.IntVar() # 定义plcflag和serflag_1整型变量用来存放选择行为返回值0或者1
serflag_1 = tk.IntVar()
serflag_2 = tk.IntVar()
plcflag.set(0) # 设置三个复选框的默认状态,1为选中,0为未选中
serflag_1.set(1)
serflag_2.set(0)
l1 = tk.Checkbutton(window, text='PLC抓取零件号',font = ('楷体', 12),variable=plcflag)
l1.place(x=10,y=60,width=130,heigh=20)
l1.config(state='normal')
l2 = tk.Checkbutton(window, text='串口1抓取测量数据',font = ('楷体', 12),variable=serflag_1)
l2.place(x=10,y=90,width=160,heigh=20)
l2.config(state='normal')
l3 = tk.Checkbutton(window, text='串口2抓取测量数据',font = ('楷体', 12),variable=serflag_2)
l3.place(x=10,y=120,width=160,heigh=20)
l3.config(state='normal')
btnStart = tk.Button(window, text = "开始采集", command = Start)
btnStart.place(x=10,y=200,width=80,heigh=30)
btnStop = tk.Button(window, text = "停止采集", state = 'disabled',command = Stop)
btnStop.place(x=110,y=200,width=80,heigh=30)
filePath = tk.StringVar(value = os.getcwd())
labelfilePath = tk.Label(window,text = '保存路径:')
labelfilePath.place(x=10,y=500,width=80,heigh=20)
entryfilePath = tk.Entry(window,width = 35, textvariable = filePath)
entryfilePath.place(x=100,y=500,width=300,heigh=20)
labelRunInf = tk.Label(window,font = ('楷体', 15), text="串口列表:")
RunInf = tk.StringVar(value = '请勾选通信方式') #定义TK字符变量,储存提示信息
labelInf = tk.Label(window,font = ('楷体', 15),textvariable = RunInf)
labelRunInf.place(x=0,y=10,width=100,heigh=20)
labelInf.place(x=100,y=10,width=150,heigh=20)
labeloil = tk.Label(window,font = ('楷体', 15), text = '油道(串口1)')
labeloil.place(x=10,y=340,width=120,heigh=30)
labelwater = tk.Label(window,font = ('楷体', 15), text = '水道(串口2)')
labelwater.place(x=10,y=380,width=120,heigh=30)
labelyali = tk.Label(window,font = ('楷体', 15), text = '测试压力')
labelyali.place(x=350,y=300,width=120,heigh=30)
labeljieguo = tk.Label(window,font = ('楷体', 15), text = '测量结果')
labeljieguo.place(x=550,y=300,width=120,heigh=30)
labelyali1=tk.Label(window,font = ('楷体', 15), text = '测试压力')
labelyali1.place(x=350,y=340,width=120,heigh=30)
labelyali2 = tk.Label(window,font = ('楷体', 15), text = '测试压力')
labelyali2.place(x=350,y=380,width=120,heigh=30)
labeljieguo1 = tk.Label(window,font = ('楷体', 15), text = '测量结果')
labeljieguo1.place(x=550,y=340,width=120,heigh=30)
labeljieguo2 = tk.Label(window,font = ('楷体', 15), text = '测量结果')
labeljieguo2.place(x=550,y=380,width=120,heigh=30)
OutputText = tk.Text(window, wrap = tk.WORD, width = 800, height = 40, font = ('TimesNewRoman',10))
OutputText.place(x=10,y=540,width=800,heigh=40)
ser1 = serial.Serial()#定义两个串口变量
ser2 = serial.Serial()
labeltime = tk.Label(window,text = '')#定义时间标签
labeltime.place(x=800,y=0,width=100,heigh=40)#定义时间标签位置
time_flag=True#时间显示随窗口初始化就产生了,所以定义在主线程里面
t=threading.Thread(target=Showtime)#定义时间线程
t.start()#启动时间线程
def S_time(event):
print(btnStop['state'])
def Killtime(event):
global time_flag#如果函数内部 修改 外部变量必须先声明为全局变量
global t1_flag
global t2_flag
t1_flag=False#这里发生修改动作,如果只是引用外部变量就不用声明全局变量
t2_flag=False
time_flag = False
window.bind('<Button-3>',S_time)#在tk窗口绑定鼠标右键激发事件s-time
window.bind('<Destroy>',Killtime)#在tk窗口绑定鼠标右键激发事件killtime
window.mainloop()#窗体呈现,需要注意的是窗体循环执行的只有关键事件,例如按钮变量等等
程序运行时偶尔会报错如下:
Exception in thread Thread-26:
Traceback (most recent call last):
File "C:\Users\ni799\AppData\Local\Continuum\anaconda3\lib\threading.py", line 926, in _bootstrap_inner
self.run()
File "C:\Users\ni799\AppData\Local\Continuum\anaconda3\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:/Users/ni799/.spyder-py3/tongxun.py", line 148, in Showtime
if btnStop['state'] == 'disabled':
File "C:\Users\ni799\AppData\Local\Continuum\anaconda3\lib\tkinter\__init__.py", line 1489, in cget
return self.tk.call(self._w, 'cget', '-' + key)
_tkinter.TclError: invalid command name ".!button2"
如果屏蔽对按钮状态的判断则不会报错,请问哪里有错误?请帮忙指正,十分感谢!
屏蔽如下字段程序则不会报错:
if btnStop['state'] == 'disabled':
if plcflag.get() == 0 and serflag_1.get() == 0 and serflag_2.get() == 0:
btnStart['state'] = 'disabled'
else:
btnStart['state'] = 'normal'