2016-11-13 9 views
0

シリアルリーダーが常にバックグラウンドで動作している間に、GUIを維持するアプリケーションを構築する必要があります。シリアルリーダーは、私のGUIに表示する必要がある変数を更新します。それが今である私のGUIが開いて、すぐに私はそれを閉じて、シリアルが読み取りを開始したようシリアルリーダーが動作している間にPythonを実行する

# These variables are updated by the reader. 
var1 = 0 
var2 = 0 
var3 = 0 

#Serial reader 
def readserial(self): 
ser = serial.Serial(port='COM4', baudrate=9600, timeout=1) 
while 1: 
    b = ser.readline() 
    if b.strip(): 
     #Function to set variables var1,var2,var3 
     handle_input(b.decode('utf-8')) 

#Simple GUI to show the variables updating live 
root = Tk() 
root.title("A simple GUI") 

gui_var1 = IntVar() 
gui_var1.set(var1) 

gui_var2 = IntVar() 
gui_var2.set(var2) 

gui_var3 = IntVar() 
gui_var3.set(var3) 

root.label = Label(root, text="My Gui") 
root.label.pack() 

root.label1 = Label(root, textvariable=gui_var1) 
root.label1.pack() 

root.label2 = Label(root, textvariable=gui_var2) 
root.label2.pack() 

root.label3 = Label(root, textvariable=gui_var3) 
root.label3.pack() 

root.close_button = Button(root, text="Close", command=root.quit) 
root.close_button.pack() 

#Start GUI and Serial 
root.mainloop() 
readserial() 

:これまでのところ、私はこれを持っています。

+0

あなたは 'mainloop()'はルートウィンドウが破壊されるまで戻りません。 –

+0

これで 'while 1'と' mainloop'をループさせる必要があります。彼らは同時に働かなければならない。あなたは 'threading'モジュールをユーザが分離したスレッドで' while 1 'を実行するようにすることができます。または 'root.after(miliseconds、function_name)'を実行して 'ser.readline()...'を定期的( 'while 1'なし)に実行します。 'readline'がデータを待っているプログラムをブロックした場合、' after'は動作しません。 – furas

+0

私はここで2つのループを扱っていることを知っています。私は私の質問が「どのように私はこれらの2つのループを同時に動かすのですか?」と要約することができると思います。 –

答えて

2

root.after(miliseconds, function_name_without_brackets)を使用して、readserialの機能を定期的に実行することができます(while 1なし)。

仮想COMポート/dev/pts/5/dev/pts/6を持つLinuxでテストされています。

import tkinter as tk 
import serial 

# --- functions --- 

def readserial(): 
    b = ser.readline() 
    if b.strip(): 
     label['text'] = b.decode('utf-8').strip() 
    # run again after 100ms (mainloop will do it) 
    root.after(100, readserial) 

# --- main --- 

ser = serial.Serial(port='COM4', baudrate=9600, timeout=1) 
#ser = serial.Serial(port='/dev/pts/6', baudrate=9600, timeout=1) 

root = tk.Tk() 

label = tk.Label(root) 
label.pack() 

button = tk.Button(root, text="Close", command=root.destroy) 
button.pack() 

# run readserial first time after 100ms (mainloop will do it) 
root.after(100, readserial) 

# start GUI 
root.mainloop() 
+0

私はこのようにすることはできません、シリアル読み取り機能を中断せずに実行するか、受信した読み取り値が不完全です。 –

+0

もちろん、このようにすることができます。シリアルポートは、データを読み込む準備ができるまでデータをバッファします。バッファがすぐにいっぱいになるとデータが失われる可能性があります。解決策はシリアルポートから頻繁に読み取ることです。 – scotty3785

関連する問題