Tkinter and Thread - ошибка после закрытия приложения - PullRequest
0 голосов
/ 19 сентября 2018

Я создал интерфейс Python для отображения некоторой информации на экране во время сбора данных через последовательный порт.Связь осуществляется с микроконтроллером ATmega.Последовательный порт должен отправлять данные, как только я нажимаю кнопку «Пуск», затем он отправляет символ команды на микроконтроллер ('g' = go).Если я нажму кнопку Закрыть , данные должны прекратить отправку (кнопка Закрыть отправляет другой символ команды, 's' = стоп).

Я знаю, что это былоневозможно создать еще один цикл внутри программы при использовании tkinter (может вызвать сбои и сбой в работе).Решением было бы создание потоков.Поэтому я создал Thread для чтения данных параллельно циклу tkinter.Каждый отправляемый блок данных заканчивается на '\n', поэтому мне пришлось использовать команду readline().

Вот упрощенный код

from tkinter import *
from tkinter import ttk
import time
import serial
import threading

ser = serial.Serial(
        port = 'COM3', 
        baudrate=9600,
        parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_ONE,
        timeout=None,
        bytesize= serial.EIGHTBITS)

ser.flushInput()
if ser.isOpen() == False:
    ser.open()

def raise_frame(frame):
    frame.tkraise()

def finish():

    ser.write('s'.encode())
    time.sleep(1)
    ser.close()
    root.destroy()

def start():
    ser.write('g'.encode())
    thread.start()

def readSerial():
    while True:
        DATA = ser.readline()
        print(DATA)

def force_close(event):
    ser.write('s'.encode())
    time.sleep(1)
    ser.close()
    root.destroy()


root = Tk()
root.attributes("-fullscreen", True)
w, h = root.winfo_screenwidth(), root.winfo_screenheight()

f1 = Frame(root)
f1.place(x=0,y=0, relheight=1, relwidth=1)

# =============================================================================
# Start Button
# =============================================================================
btn_start=Button(f1, text="Start",font = ("Arial Bold",30), command = start)
btn_start.pack(padx=10,pady=30, side = BOTTOM)

# =============================================================================
# Close Button
# =============================================================================
close_value=BooleanVar()
btn_close=Button(f1, text="Close",font = ("Arial Bold",30), command=finish)
btn_close.pack(padx=10,pady=30, side = BOTTOM)

thread=threading.Thread(target=readSerial)
thread.daemon=True 
root.bind('<Escape>',force_close)
raise_frame(f1)
root.mainloop()

Проблема в том, что каждый раз, когда язакрыть приложение, появляется эта ошибка:

Exception in thread Thread-8:
Traceback (most recent call last):
  File "C:\Users\apoco\Anaconda3\lib\threading.py", line 916, in _bootstrap_inner
    self.run()
  File "C:\Users\apoco\Anaconda3\lib\threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "<ipython-input-2-838b466f09c9>", line 41, in readSerial
    DATA = ser.readline()
  File "C:\Users\apoco\Anaconda3\lib\site-packages\serial\serialwin32.py", line 269, in read
    win32.ResetEvent(self._overlapped_read.hEvent)
AttributeError: 'NoneType' object has no attribute 'hEvent'

Кто-нибудь знает, как справиться с этой ошибкой?

Я искал в Stackoverflow, но не нашел подобной проблемы.

...