我最近剛剛做了這個來監測串口設備的輸入。您需要能夠在準備好時接收串行數據,並保持Tk事件循環運行。您可以使用工作線程讀取串行數據並將輸入發佈到UI線程以供顯示,也可以使用Twisted框架。在我的情況下,我使用了扭曲來避免從串口讀取任何阻塞信息,並使用畫布線將值繪製成簡單的線圖。
#!/usr/bin/python
import sys
from Tkinter import *
from ttk import *
from twisted.internet import tksupport, reactor
from twisted.internet.serialport import SerialPort
from twisted.protocols import basic
class DeviceProtocol(basic.LineReceiver):
#delimiter = "\r\n" # default delimiter is crlf
def __init__(self, callback):
self.callback = callback
def lineReceived(self, data):
self.callback.OnDataReceived(data)
class MainWindow(Frame):
def __init__(self, parent, title):
self.data = [(n,1) for n in range(100)]
self.sample = len(self.data)
Frame.__init__(self, parent)
parent.wm_withdraw()
parent.wm_title(title)
self.CreateUI()
self.grid(sticky = (N,S,W,E))
parent.wm_protocol("WM_DELETE_WINDOW", self.onDestroy)
parent.grid_rowconfigure(0, weight = 1)
parent.grid_columnconfigure(0, weight = 1)
parent.wm_deiconify()
def CreateUI(self):
canvas = Canvas(self, background="white")
canvas.create_line((0, 0, 1, 1), tag='Plot', fill='red', smooth=True)
canvas.grid(sticky = (N,S,W,E))
self.canvas = canvas
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
def onDestroy(self):
reactor.stop() # required to cleanly shutdown twisted event loop
def Monitor(self, port, baudrate = 9600):
self.serial = SerialPort(DeviceProtocol(self),
port, reactor, baudrate=baudrate)
def OnDataReceived(self, data):
print data
for v in data.split():
self.data.append((self.sample, int(v)))
self.sample += 1
if len(self.data) > 100:
self.data = self.data[-100:]
self.after_idle(self.OnUpdatePlot)
def OnUpdatePlot(self):
width = self.canvas.winfo_width()
height = self.canvas.winfo_height()
xS,yS = self.data[0]
xE,yE = self.data[-1]
coords = []
fx = width/(xE - xS)
fy = height/100 # y values are 0 < y < 100
for (x,y) in self.data:
coords.append(fx * (x - xS))
coords.append(fy * (100 - y))
self.canvas.coords('Plot', *coords)
def main(argv = None):
if argv is None:
argv = sys.argv
if len(argv) != 2:
print "usage: plot_serial <serialport>"
return 1
root = Tk()
tksupport.install(root) # register the Tk event loop with twisted
main = MainWindow(root, "Plot serial data")
main.Monitor(argv[1])
reactor.run() # use twisted instead of root.mainloop()
return 0
if __name__ == '__main__':
sys.exit(main())
您是否收到錯誤?如果我將系列調用註釋掉並將「顏色」的值設爲「紅色」,它對我來說工作正常。如果我不得不猜測,我會說'顏色'應該給你一個「未知顏色名稱」的錯誤,你需要將你的顏色名稱格式化爲Tkinter可接受的字符串。 – atlasologist
但是,我確實得到了關於顏色的一些錯誤,我認爲這只是由於與串行時間有關。在我發現如何將RGB顏色轉換爲Tkinter接受的HTML顏色後,顏色正常工作。 – mECH