[PyQt] GUI 생성 비동기 처리 구현

이정찬·2022년 5월 20일
0

PyQt

목록 보기
3/6
post-thumbnail

2021년 8월부터 2021년 11월까지 진행된 PyQt를 이용한 스마트팩토리 외주에서 배운 사항들을 정리하기 위해 작성한 글입니다.
Raspberry Pi 3 환경에 Raspbian OS를 설치하여 진행하였습니다.

1. 예상치 못한 GUI 로딩 문제

성공적으로 Arduino 센서에 serial communication 코드를 업로드하고, python 에서 Arduino 센서의 값을 받아서 이제 모든 것이 마무리 되는가 싶었지만, 예기치 못한 문제가 발생했습니다.

프로그램 구동 시, UI가 로딩되면서 즉시 값을 받아오도록 코딩을 해 놓았지만, 제 생각대로 작동이 되지 않았습니다. 센서가 연결되고, 통신이 시작되는 시간보다 UI의 로딩이 더 빨라서 UI가 로딩 된 직후 센서의 값을 받아오려고 하면, 센서의 연결이 아직 완료되지 않아서 에러가 발생하는 것이었습니다.

예외처리를 통해 프로그램이 종료하는 것은 방지하였지만, 당초 프로젝트의 목적상 센서가 연결되지 않았을 때 초기값이 서버에 전달되는 것은 취지에 맞지 않았습니다. 초기값일 때는 값을 전달하지 않을 수도 있었지만, 유지보수에 어려움이 있을 것 같았습니다. 따라서, UI 로딩에 비동기 처리를 적용해서 센서의 연결이 종료된 후, 로딩을 진행할 수 있도록 코딩을 하여야 했습니다.

2. PyQt의 함수 비동기 처리

먼저 비동기 처리를 하려면, 비동기 함수를 선언해야 합니다. python 3.5 버전 이후로는 async/await 키워드가 정규 문법입니다. 그리고 asyncio 라이브러리가 python 3.4 버전 이후로 내장 라이브러리로 채택이 되면서, 어떤 프로젝트에서든 사용할 수 있게 되었습니다.

import asyncio
...

async def fun(self):
	...

python의 함수 선언식에서, 앞에 async만 붙여 주면 그 함수는 비동기 함수가 됩니다. 이렇게 비동기로 선언한 함수들을 순서에 맞게 실행시켜주면 됩니다. 또는 다른 함수나 모듈들을 await로 선언하여 사용할 수 있게 됩니다.

3. 함수의 순차적 시행

이렇게 선언한 async 함수들을 순차적으로 시행할 수 있게 도와주는 함수가 asyncio 라이브러리에 존재합니다. get_event_loop() 함수와 run_until_complete() 함수입니다.

# weldingProcess.py
import asyncio
...

class WeldingProcess(QtWidgets.QMainWindow):
	def __init__(self):
    	...
        loop = asyncio.get_event_loop()
        loop.run_until_complete(asyncio.gather(self.makeObject(), self.makeWidget())
        
    async def makeObject(self):
    	await asyncio.sleep(10)
        ...
    
    async def makeWidget(self):
    	await asyncio.sleep(1)
        ...

makeObject() 함수와 makeWidget() 함수를 비동기처리하여 순차적으로 시행하게 해주는 코드입니다. 최초 실행 속도가 별로 상관 없는 프로그램 이었으므로, 함수 내부에 await으로 sleep() 함수를 실행하여 혹시 센서 연결이 늦어질때를 대비하였습니다. makeObject() 함수에서 모든 센서의 연결이 완료되면, makeWidget() 함수에서 UI를 생성하여, 값 통신을 시작합니다.

4. 마치며

Javascript를 사용하여 Node.js express 서버를 개발할 떄나, React, Next.js에서 api를 호출할 때 등 요즘은 callback 함수의 사용(promise 용법)보다 비동기 처리(async/await)가 훨씬 가독성이 좋다고 느껴질 때가 많습니다. Javascript로만 비동기 처리를 해봤었는데, python에서도 편하게 비동기 처리가 가능했다는 사실을 배웠습니다.

profile
개발자를 꿈꾸는 사람

0개의 댓글