PySimpleGUI 및 multithread 사용 예

입문


PysimpleGUI는 사용하기 좋기 때문에 이전에 사용했던 LabVIEW의 디자인 모델 중 하나인'Cumessage 처리 프로그램 디자인 모델'을 실현할 수 있는지에 주력한 결과입니다.
LabVIEW 대기열 메시지 처리기 설명
응용 프로그램 설계 모델: 생산자/소비자
[LabVIEW 스킬 승급] 디자인 모델'QMH'는?
LabVIEW에 대해서는 Wiki 등을 참조하십시오. 측정 장치의 제어 프로그램에서 자주 사용됩니다.(최근에 Python에 눌렸어요.)
특징은 도형 프로그래밍이다. while 순환만 쓰면 핵심이나 라인을 사용한다.따라서 While 순환을 채우면 다중 작업이 됩니다.대기열 메시지 처리 프로그램 설계 모드는 대기열에서 While 순환 사이의 데이터 교환을 하는 것입니다.

환경


지난번 보도PysimpleGUI의 시간 표시(timeout 사용법)와 같다.
Win10Pro
Anaconda
Python3.7

하고 싶은 일


PysimpleGUI는 이벤트(버튼 누르기, 입력 등 이벤트)와 처리된 데이터가 UI에 표시되기를 기다립니다.다중 루틴을 사용하여 데이터를 대기열을 통해 받은 이벤트를 처리하는 함수로 보냅니다.함수는 받은 데이터에 따라 처리하고 결과를 대기열 형식으로 되돌려줍니다.
스레드 간 통신 (프로세스 간 통신) 도 전역 변수를 사용할 수 있지만, 이번에는 대기열을 사용합니다.
그림에 쓰면 다음과 같다.

참조된 데모 프로그램은 Demo_Multithreaded_Multiple_Threads 입니다.
참고로 Demo_Multithreaded_Long_Task_Simple 전역 변수를 사용합니다.

생성된 코드


from queue import Queue
from threading import Thread
import time

import PySimpleGUI as sg

ui_que = Queue()
data_que = Queue()

def show_time():
    jikan = time.strftime('%p %I:%M:%S')
    return jikan

def worker(data_que,ui_que):
    result = data_que.get()
    time.sleep(1)
    ui_que.put(result[0])

def worker_do(data_que,ui_que):
    result_do = data_que.get()
    time.sleep(0.5)
    ui_que.put(len(result_do))


sg.theme('Dark')
layout = [
          [sg.Text(size=(15, 1), font=('Helvetica', 20),justification='center', key='-jikan-')],
          [sg.Text('Data', size=(8, 1)),sg.Input(key='-data-')],
          [sg.Submit()],
          [sg.Text('Data2', size=(8, 1)),sg.Input(key='-data2-')],
          [sg.Button('DO',key='-do-'), sg.Cancel()],
          [sg.Text('Status:', size=(8, 1)),sg.Text('',size=(8,1), key='-status-')],
          [sg.Output(size=(70, 2))]
          ]

window = sg.Window('template',layout)

while True:
    event, values = window.read(timeout=100,timeout_key='-timeout-')
    # event, values = window.read()
    #timeoutを指定することで、timeoutイベントが起こります。timeoutの単位ms
    # print(event,values)
    #↑コメントアウトを外すと、どんなイベントが起こっているか確かめることができます。
    if event in (None,'Cancel'):
        break
    elif event in 'Submit':
        print('Input data: {}'.format(values['-data-']))
        # デーモンスレッドはデーモンスレッド以外のスレッドがなくなった時点で全て自動終了する
        thread = Thread(target=worker, args=(data_que,ui_que), daemon=True).start()
        data_que.put(values['-data-'])

    elif event in '-do-':
        print('do somthing: {}'.format(values['-data2-']))
        thread_do = Thread(target=worker_do, args=(data_que,ui_que), daemon=True).start()
        data_que.put(values['-data2-'])

    elif event in '-timeout-':
        jikan = show_time()
        window['-jikan-'].update(jikan)

        try:
            ui_data=ui_que.get_nowait()
        except :
            ui_data = None
        if ui_data:
            print(ui_data)   
            window['-status-'].update(ui_data)


window.close()

실행 예시 및 코드 설명


Data에 숫자와 문자를 넣고 Submit를 누르면 첫 번째 문자가 되돌아옵니다.
마찬가지로 Data2 에 숫자와 문자를 넣고 Do 를 눌러 입력한 문자열의 길이를 되돌려줍니다.layoutsg.Output 출력 코드의 print에 적힌 곳.submit 단추를 누르면 worker1 라인이 올라가 data 로 전송됩니다 data_que.worker1 처리, ui_que 결과 발송.do 버튼도 동일하게 처리됩니다.
지난번 보도에서 말한 바와 같이 window.readtimeout를 이용하여 상태 감시를 한다.timeoutelif으로 명확하게 쓰여 있다.(나는 파이톤의 정책으로 명확하게 쓰는 것이 좋다고 생각한다.)ui_que.get_nowait() 에서 정보가 없으면 오류가 표시됩니다.우리는 오류를 수신하기 위해 try-except 를 사용한다.

총결산


PysimPleGUI로 LabVIEW에서 자주 사용하는 대기열 메시지 처리 프로그램 설계 패턴과 비슷한 것을 만들 수 있습니다.
사용하기 쉽도록 개량하고 싶습니다.

좋은 웹페이지 즐겨찾기