Python을 사용해 데이터를 실시간으로 수집 및 저장하는 GUI 프로그램을 개발하고, 이를 독립 실행 파일(EXE)로 변환하는 과정을 진행했습니다. 보안을 위해, 코드와 데이터베이스 관련 부분은 비공개로 처리했습니다. 대신, 사용한 기술 스택과 주요 로직을 중심으로 설명했습니다.
프로젝트 진행과정은 다음과 같습니다.
- 실시간 데이터 수집: 데이터 크롤링을 통해 ODBC에 폴링 방식으로 주기적으로 저장하는 시스템 구축
- GUI 프로그램 제작: 최근 업데이트 시간을 통해 프로그램이 작동 여부 확인 기능 개발
- 실행 파일 생성: Python 코드를 EXE로 변환하여 별도의 Python 환경 없이 프로그램 실행 가능.
사용한 기술스택은 다음과 같습니다.
- Python: 주 언어로 사용.
- Tkinter: Python의 내장 GUI 라이브러리로 사용자 인터페이스 제작.
- Pillow: 이미지를 GUI에 표시하기 위한 라이브러리.
- PyInstaller: Python 코드를 EXE 파일로 변환.
구현 과정
1) 실시간 데이터 수집
- 특정 URL로 HTTP 요청을 보내 데이터를 크롤링했습니다.
- 데이터를 주기적으로 가져오기 위해 스레드(thread)와 시간 지연 함수를 활용했습니다.
핵심 기술:
- requests: HTTP 요청 및 데이터 가져오기.
- threading: 데이터 수집과 GUI 반응성을 동시에 유지.
2) GUI 제작
- Tkinter를 사용해 사용자 인터페이스를 제작.
- 주요 기능:
- 실시간 업데이트: 데이터를 실시간으로 화면에 표시.
- 이미지 표시: GUI에 배경 이미지 추가.
- 라벨(Label): 데이터베이스의 최신 업데이트 시간을 표시.
Tkinter 주요 구성 요소:
- Label: 텍스트 표시.
- Canvas: 이미지를 표시하거나 그래픽 요소를 추가.
- StringVar: 실시간 데이터 갱신을 위해 사용.
3) EXE 파일 생성
- PyInstaller를 사용해 Python 코드를 EXE로 변환.
- 외부 이미지 파일을 실행 파일에 포함하도록 --add-data 옵션을 사용.
pyinstaller --onefile --add-data "water_image.png;." --name 프로그램이름 main.py
명령어 설명:
- --onefile: 모든 파일을 단일 실행 파일로 묶음.
- --add-data: 추가 리소스(예: 이미지)를 실행 파일에 포함.
- --name: 생성될 실행 파일의 이름 지정.
Spec 파일
PyInstaller는 Python 코드를 실행 파일(EXE)로 변환할 때 spec 파일을 생성합니다. 이 파일은 PyInstaller가 EXE 파일을 생성하는 과정을 제어하는 설정 파일입니다.
Spec 파일의 주요 내용
- a = Analysis([...])
- Python 스크립트의 종속 파일과 라이브러리를 분석하고 정의합니다.
- pyz = PYZ([...])
- Python 스크립트를 실행하는 데 필요한 Python 코드와 모듈을 압축한 파일을 생성합니다.
- exe = EXE([...])
- 최종적으로 EXE 파일을 생성하는 설정을 정의합니다.
- 실행 파일 이름, 아이콘, 콘솔 표시 여부 등이 포함됩니다.
- coll = COLLECT([...])
- EXE 파일과 관련된 모든 리소스를 하나로 모읍니다.
- 추가할 데이터 파일이나 디렉토리를 여기에 정의할 수 있습니다.
주요 기술적 초점
1) 데이터 수집과 GUI 동시 실행
- Python의 threading을 활용해 GUI와 데이터 수집을 동시에 처리.
- GUI는 Tkinter의 메인 스레드에서 실행되고, 데이터 수집은 백그라운드 스레드에서 동작.
2) 리사이징 필터
- 이미지를 GUI에 표시하기 위해 Pillow 라이브러리를 사용.
- 최신 Pillow 버전에서는 리사이징 필터로 Image.Resampling.LANCZOS를 사용해 고품질로 이미지 크기를 조정.
3) 실행 파일의 독립성
- EXE 파일로 변환하면서 외부 라이브러리 및 리소스를 포함해 독립 실행 가능하도록 설정.
- 추가 데이터 파일(예: 이미지)을 실행 파일에 포함하여 별도의 환경 설정 없이 실행 가능.
트러블 슈팅
프로젝트를 진행하는 과정에서 크게 두가지 트러블이 일어났습니다.
1) 라이브러리 누락 문제
- PyInstaller가 모든 라이브러리를 자동으로 포함하지 못해 --hidden-import 옵션을 사용하여 해결.
pyinstaller --hidden-import "PIL" --onefile main.py
2) PyInstaller로 생성된 EXE 파일이 보안 프로그램(예: 알약)에서 악성코드로 감지되어 중지되는 문제
PyInstaller는 Python 코드와 관련된 모든 라이브러리, 종속 파일을 하나의 EXE 파일로 묶습니다. 이를 실행 시, EXE 파일은 내부에 포함된 패키지를 임시 디렉토리에 압축 해제한 후 실행합니다.
이 과정이 일부 악성코드(예: 패커, 드로퍼)가 사용하는 기술과 유사하기 때문에 보안 소프트웨어에서 오탐지될 수 있습니다. 또한 실제로 악성코드 작성자들이 PyInstaller를 악용해 악성코드를 생성하는 경우가 있고 PyInstaller로 생성된 EXE 파일은 디지털 서명이 없는 상태로 배포되기 때문에 보안프로그램에서 PyInstaller로 생성된 EXE를 중지 시킨 것입니다.
EXE 파일 생성 전에 보안 소프트웨어(알약 등)의 실시간 감지 기능을 일시적으로 비활성화합니다.
3) ODBC 드라이버와 파이썬 비트가 일치하지 않아서, 자동 저장이 안 되는 문제
제가 사용한 파이썬은 64비트였고, odbc는 32비트 드라이버가 설치되어 있는 상황이었습니다. odbc드라이버가 32비트가 이미 설치되어있다면 64비트를 설치하는 것이 굉장히 어렵기 때문에 , 파이썬 비트를 교체해야합니다.
파이썬 64비트를 지우고 , 32비트를 설치하셔도되고 기존 파이썬을 지우지않고 두개를 깔아서 원할 때마다 시스템 환경변수를 바꿔서 사용가능합니다. 더 자세한 트러블 슈팅은 다음 링크에 기술해놓았습니다.
프로젝트를 마무리하며
이번 프로젝트를 통해 항상 웹사이트를 통해서만 배포하던 방식에서 벗어나, 처음으로 Python 코드를 기반으로 독립 실행 파일(EXE)을 만들어보는 경험을 했습니다. 특히, 배포 과정에서 발생한 다양한 문제를 해결하며, 성취감과 함께 더 많은 지식을 얻을 수 있었습니다.
직접 만든 EXE 파일이 단순히 동작하는 것을 넘어, 데이터 자동 수집/저장 및 실시간 모니터링 기능을 구현하며, 이를 기반으로 빅데이터 기반 SCADA 등 자동 제어 프로그램에 대해서도 관심을 갖게 되었습니다.