Külön külön már sikerült megvalósítanom a feladatokat. Azaz felépítettem egy grafikus felületet a programom számára, és sikerült adatokat fogadni illetve küldeni soros porton keresztül. Most viszont ezeket egy programban szeretném megvalósítani. Mivel a soros porton érkező adatok kiszámíthatatlan gyakorisággal érkeznek ezért azt folyamatosan (rendszeres időközönként) figyelni kell. A Grafikus kezelői felületetet a felhasználó szintén kiszámíthatatlan módon használja. Erre a megoldás a "Thread"-ek (szálak) használata Pythonban.
A példát nem magyarázom tovább, mert igyekeztem sok-sok kommentet beleírni a kódba:
# -*- coding: cp1250 -*- from Tkinter import * import Tkinter import time import threading import random import Queue import serial #-------------------------------------------------------------------------------- class GuiPart: def __init__(self, master, queue, endCommand): """ Grafikus felület definiálása: feliratok, gombok, Text mező-az érkező adatok megjelenítéséhez """ self.queue = queue #GUI definiálás cimke1 = Tkinter.Label(master, text = 'Soroson érkezik:') gomb01 = Tkinter.Button(master, text='Clear-Delete', command=endCommand) cimke1.grid(row =0, column=1) gomb01.grid(row =1, column=0) keret = Frame(master, borderwidth=2, relief=RIDGE) scrollbar = Scrollbar(keret) scrollbar.pack( side = 'right', fill='y') #keretben lesz egy Text mező(uzi), amihez a görgetősávot(scrollbar) definiáljuk global uzi uzi = Tkinter.Text(keret, font=("Helvetica", 10), bg='white', width = 50, height = 4, yscrollcommand = scrollbar.set) keret.grid(row =1, column =1, sticky =E) uzi.pack() scrollbar.config( command = uzi.yview ) def processIncoming(self): """ Kiolvassa a queue-t ha van benne valami, elmenti azokat a save.txt fájlba és kiírja a grafikus felületre is """ while self.queue.qsize(): try: msg = self.queue.get(0) f = open('save.txt', 'a') f.write(str(msg)+'\n') f.close() uzi.insert(END, msg+'\n') except Queue.Empty: pass #-------------------------------------------------------------------------------- class ThreadedClient: """ Elindítja a grafikus felületet és a soros portot figyelő szálat """ def __init__(self, master): self.master = master # queue létrehozása self.queue = Queue.Queue() # Grafikus felület létrehozása self.gui = GuiPart(master, self.queue, self.endApplication) #Port megnyitása és Soros portnak szál(threading) megnyitása try: self.ser = serial.Serial(port=9, timeout=5) except serial.SerialException: print "Nem sikerült a kapcsolatot létrehozni az eszközzel" exit(0) print self.ser.portstr + ' port megnyitva' #szál létrehozása/indítása self.running = 1 self.thread1 = threading.Thread(target=self.workerThread1) self.thread1.daemon = True self.thread1.start() #periodikus ellenőrzés indítása: van valami a queue-ban? self.periodicCall() def periodicCall(self): """ 100 ms -ként ellenőrzi van-e valami a queue-ban """ self.gui.processIncoming() if not self.running: # This is the brutal stop of the system. You may want to do # some cleanup before actually shutting it down. import sys sys.exit(1) self.master.after(100, self.periodicCall) def workerThread1(self): """ Itt kezeljük a soros porton érkező adatokat Amennyiben érkezik valami betölti a queue-ba """ i = 1 line = '' while self.running: try: line = self. ser.readline() except serial.SerialException: print "Kapcsolat megszakadt" if line !='': self.queue.put(line) else: line = str(i) i = i+1 self.queue.put('Nem érkezett adat /Timeout/ ('+line+'.)') def endApplication(self): """ Törli az beérkezett adatokat a fájlból, ahova elmentette azokat korábban """ f = open('save.txt', 'w') f.write(' ') f.close() uzi.delete(1.0, END) #self.ser.close() #-------------------------------------------------------------------------------- rand = random.Random() root = Tkinter.Tk() root.title("Soros port figyelés") root.minsize(400,100) root.maxsize(500,150) client = ThreadedClient(root) root.mainloop() |
Köszönet a forrásért, amiből kiindulhattam. Így egy picit továbbfejlesztve megszülethetett ez a program.