我是python和tkinter的新手。。。我使用Tkinter显示仪表并通过串行com接收信息。我已经准备好GUI,现在需要读取序列值。
我面临的问题是我不能连续读取串行COM。我遇到了self.after
,但它仍然不起作用。基本上它不会在控制台上显示任何值。知道可能出了什么问题吗?
这是主要代码。我还有一个文件meter.py
import tkinter as tk
import meter as m
import serial
class Mainframe(tk.Frame):
def __init__(self,master,*args,**kwargs):
super(Mainframe,self).__init__(master,*args,**kwargs)
self.meter = m.Meter(self,height = 400,width = 400)
self.meter.setrange(20,90)
self.meter.pack()
tk.Scale(self,width = 15 ,from_ = 20, to = 90
,orient = tk.HORIZONTAL
,command = self.setmeter).pack()
tk.Button(self,text = 'Quit',width = 15,command = master.destroy).pack()
tk.Button(self,text = 'Zoom',width = 15).pack()
def setmeter(self,value):
value = int(value)
self.meter.set(value)
class App(tk.Tk):
def __init__(self):
super(App,self).__init__()
self.title('Try Meter')
Mainframe(self).pack()
def serie():
ser = serial.Serial('COM2', 2400, timeout=1)
line = ser.readline() # read a '\n' terminated line
print (line)
self.after(100,serie)
App().mainloop()
代码不能按预期工作的原因是您从未调用App
类的serie()
方法。如果您修改代码以添加此调用,也许在__init__()
方法的末尾,您应该会看到串行数据被打印到控制台。
然而,在同一个线程中处理串行IO和用户界面不是一个好主意。如果没有任何数据要从串行端口读取,readline()
将阻塞长达1秒(初始化串行端口时设置的超时值)。这将阻塞tk主循环,并且您的用户界面将完全没有响应。在我看来,解决这个问题的最好方法是使用一个异步IO库。我喜欢Twisted,因为它内置了对tk(示例)和串行通信的支持,但还有其他几个选项。如果这感觉有点过分,您还可以分别使用线程
或多重处理
模块将串行轮询代码移动到自己的线程或进程。
回答问题的第二部分:
在readSerial()
中,您创建了Mainframe()
的一个新实例,但我认为您实际想要做的是使用在应用程序
类的
初始化()方法中创建的实例。您需要使用类似于
self的代码将其存储为属性。main\u frame=Mainframe(self)
,然后在readSerial()
中,您可以使用根目录访问它。主框架。设置计(50)
。
让它工作起来。这是密码
class Mainframe(tk.Frame):
def __init__(self,master,*args,**kwargs):
super(Mainframe,self).__init__(master,*args,**kwargs)
self.meter = Meter(self,height = 400,width = 400)
self.meter.setrange(20,90)
self.meter.pack()
tk.Scale(self, width = 15, from_ = 20, to = 90, orient = tk.HORIZONTAL,
command = self.setmeter).pack()
tk.Button(self,text = 'Quit',width = 15,command = master.destroy).pack()
tk.Button(self,text = 'Zoom',width = 15).pack()
self.setmeter(15)
def setmeter(self,value):
value = int(value)
self.meter.set(value)
class App(tk.Tk):
def __init__(self):
super(App,self).__init__()
self.title('My Meter')
Mainframe(self).pack()
root = App()
serBuffer =b""
aux=""
def readSerial():
serBuffer=b""
while True:
c = ser.read() # attempt to read a character from Serial
#was anything read?
if len(c) == 0:
#print("cero")
break
#else:
#print (len(c))
if c == b'\n' :
#we have all the info
aux = serBuffer.split(b" ")
print (aux[0]," ",aux[1])
miinstance= Mainframe()
miinstance.setmeter(50)
#root.update()
serBuffer = "" # empty the buffer
else:
serBuffer+=c# add to the buffer
#aux= str(serBuffer, 'utf-8')
root.after(700, readSerial) # check serial again soon
root.after(1000, readSerial)
root.mainloop()
顺便说一句,我知道我正在努力更新仪表。当我收到一个完整的字符串(由\n检测)我想传递该值的小部件来更新仪表。设置值的函数是seteter,但是用我的代码
miinstance= Mainframe()
miinstance.setmeter(50) <--put this value as test
我得到这个错误。第一行是接收到的串行字符(正确)
b'90' b'0'
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files\Python 3.5\lib\tkinter\__init__.py", line 1535, in __call__
return self.func(*args)
File "C:\Program Files\Python 3.5\lib\tkinter\__init__.py", line 582, in callit
func(*args)
File "C:/Users/MARTIN/Documents/Personal/phyton/Nuevo anemometer/read_serie_v2.py", line 258, in readSerial
miinstance= Mainframe()
TypeError: __init__() missing 1 required positional argument: 'master'
我试图把“master”作为一个参数,但它说“master”没有定义。
我的代码(最初是从web上获得的)在GUI中有一个比例,
tk.Scale(self,width = 15 ,from_ = 20, to = 90
,orient = tk.HORIZONTAL
,command = self.setmeter).pack()
当我移动它时,它会更新仪表,但我不需要它。仪表应根据收到的序列信息进行更新。
你知道哪里不对吗?
我试图读取3温度设备使用WinForm和Modbus 485协议。基本上,我必须定期向每个设备写入命令,等待响应,当我得到响应时,处理它。每个设备都有一个唯一的通信地址。为了定期发送命令,我使用了计时器。这就是我发送命令的方式和处理响应的地方: 对于每个设备,等等。这是我的serialport数据接收事件: 所以我的沟通应该是: 然后再次发送命令device1。问题是,我有时得到通信超时错误,我知
我无法通过串行连接读取来自arduino的串行数据。为了解决串行和gui需要同时运行的问题,我使用了。函数后,每100ms调用一次更新序列。然而,当我运行这段代码时,没有弹出窗口,并且我得到一个错误,说我已经超过了最大递归深度。这是我的密码:
这是http://www.gravitech.us/7segmentshield.html给出的代码。 那么怎样才能逐行阅读呢?
我正在尝试使用shell和java的组合来读取和写入串行端口。目标是能够使用PrintWriter和BufferedReader从连接到串行端口的设备发送和接收命令。我知道这可以用不同的方式来实现(不使用shell),但这不是我想要的。我希望能够使用shell和java实现这一点。 这是我的代码: 有了这段代码,我特别尝试从串行端口读取数据。我使用java运行shell命令来访问串行端口,然后读取
问题内容: 给定一个不太长的字符串,逐行读取字符串的最佳方法是什么? 我知道你可以做: 另一种方法是在eol上获取子字符串: 还有其他更简单的方法吗?我对上述方法没有任何问题,只是想知道你们中是否有人知道一些看起来更简单,更有效的方法? 问题答案: 您也可以使用String方法: 这使您可以方便地将所有行排列在一起。 我不知道拆分的性能。它使用正则表达式。
我试图在一些python代码和arduino代码之间来回“乒乓”信息。我想定期向arduino代码发送两个设定点(例如,在分钟内),在arduino上读取它们 现在,我无法获得可靠的信息来来回跳转。我在搜索中没有找到任何与此类似的内容,我试图修改的所有内容都不起作用。最接近我的是这个(实际上它并没有在发送和接收之间来回切换): python 阿杜伊诺: 我最终得到的只是重复的相同值(不是实际发送的