개발자/라즈베리파이4

라즈베리파이 Python 프로그래밍 11: Tkinter를 사용한 Python GUI

지구빵집 2021. 11. 15. 10:46
반응형

 

 

라즈베리파이 Python 프로그래밍 11: Tkinter를 사용한 Python GUI 

 

이전 포스팅에서 파이선 코드를 조작하고 응용 프로그램을 구조화하는 데 중요한 개념인 파이썬 객체 지향 기능에 대해 배웠습니다. 이제 Python에서 그래픽 인터페이스를 디자인하는 방법에 대해 배워보겠습니다.

 

마이크로컨트롤러에서 개발된 임베디드 애플리케이션에는 일반적으로 LED, 문자 LCD 또는 소형 그래픽 LCD가 디스플레이 장치로 사용됩니다. 그러나 이러한 디스플레이에는 멋진 인터페이스가 많지 않습니다. 그러나 단일 보드 컴퓨터(예: Raspberry Pi)는 데스크톱 시스템처럼 구성할 수 있습니다. 사실, 우리는 Linux 데스크톱을 사용하여 Raspberry Pi(RPi)를 설정했습니다. 따라서 유사한 임베디드 회로에서 실행되는 풍부한 인터페이스와 대규모 애플리케이션을 즐길 수 있습니다.

 

마이크로컨트롤러가 속도를 제공하지만 단일 보드 컴퓨터에는 고급 언어 기능에 쉽게 액세스 할 수 있는 운영 체제를 포함하는 이점이 있습니다. 풍부한 그래픽 인터페이스, 데이터베이스 액세스, 데이터 시각화, 3D 그래픽, 네트워킹 및 데이터 마이닝은 SBC가 있는 임베디드 프로젝트에서 사용할 수 있는 HLL(High Level Language) 기능의 일부일 뿐입니다.

 

블럭다이어그램 예제와 필요한 인터페이스

 

예를 들어 센서를 마이크로 컨트롤러와 인터페이스함으로써 센서 데이터만 수집하고 수집된 데이터를 기반으로 즉각적인 조치를 구현할 수 있습니다. 그러나 동일한 센서를 단일 보드 컴퓨터(SBC)와 인터페이스 하면 다양한 작업을 수행할 수 있습니다.

 

여기에는 아래와 같은 항목이 포함됩니다.

 

  • 대량의 센서 데이터를 데이터베이스에 기록 및 유지
  • 분석 작업
  • 데이터 시각화: data visualization는 데이터 분석 결과를 쉽게 이해할 수 있도록 시각적으로 표현하고 전달되는 과정을 말한다. 데이터 시각화 목적은 도표(graph)라는 수단을 통해 정보를 명확하고 효과적으로 전달하는 것이다.
  • 데이터 마이닝 수행: 데이터 마이닝(data mining)은 대규모로 저장된 데이터 안에서 체계적이고 자동적으로 통계적 규칙이나 패턴을 분석하여 가치 있는 정보를 추출하는 과정이다. 다른 말로는 KDD(데이터베이스 속의 지식 발견, knowledge-discovery in databases)라고도 일컫는다.
  • 네트워크에 있는 다른 장치와 데이터 및 결과 공유
  • 즉각적이고 장기적인 조치를 취하는 것

펌웨어 수준 코드에서 실행되는 마이크로컨트롤러 기반 장치는 이러한 복잡한 작업을 자체적으로 수행하지 못합니다. 기껏해야 네트워크에 연결하여 사물 인터넷(IoT) 장치로 구성할 수 있습니다. 수집된 물리적 데이터는 클라우드 플랫폼에서 조작할 수 있습니다. 이것이 싱글 보드 컴퓨터(SBC)가 임베디드 영역에서 뚜렷한 역할을 하는 한 가지 큰 이유입니다.

 

또 다른 이유: 사용자는 SBC에서 작업할 때 임베디드 시스템에서 하드웨어-소프트웨어 공동 설계로 작업하게 됩니다. 마이크로컨트롤러 기반 애플리케이션이 하드웨어에 초점을 맞추는 동안 사용자는 소프트웨어 측면으로 초점을 이동할 수 있습니다. SBC를 사용하면 하드웨어 구성 요소의 성능을 사용하는 고급 임베디드 소프트웨어를 만들 수 있습니다.

 

궁극적으로 가장 의미 있는 것은 하드웨어에서 실행되는 소프트웨어입니다. LED 인터페이스 및 제어는 임베디드 시스템의 "Hello World"입니다.

 

다음은 첫 번째 LED 드라이버 레시피를 위해 설계된 그래픽 사용자 인터페이스(GUI) 스크린숏입니다. 잠시 시간을 내어 이 GUI를 검토하고 SBC, 단일 보드 컴퓨터(single-board computer)를 사용하여 하드웨어 구성 요소에 적용할 수 있는 제어 수준을 추측해 보십시오.

 

RPi LED 드라이버용 Python Tkinter GUI.

 

모든 RPi 레시피에서 GUI 프로그래밍과 멀티스레딩을 자주 사용합니다. 센서를 사용할 때 데이터 시각화, 데이터베이스 프로그래밍 및 임베디드 소프트웨어에 대한 데이터 마이닝이 포함됩니다.

 

마찬가지로 액추에이터를 제어하거나 로봇을 만들거나 정교한 하드웨어 모듈(예: 카메라 또는 마이크 등)을 사용할 때 이미지 처리, 오디오, 멀티미디어 프로그래밍, 3D 그래픽 및 게임 프로그래밍과 같은 관련 소프트웨어 기능을 포함할 수 있습니다. , 등.

 

GUI 프로그래밍과 멀티스레딩은 모든 레시피의 필수 소프트웨어 구성 요소입니다.

 

Python GUI 프로그래밍

 

Python은 강력한 VHLL(고급 언어)입니다. 풍부한 그래픽 인터페이스를 설계할 수 있으며 데이터 마이닝 기능과 함께 다양한 데이터 시각화 기술을 제공합니다. 이것은 정교한 임베디드 애플리케이션에서 뚜렷한 이점입니다.

 

임베디드 애플리케이션에서 RPi를 사용할 때 임베디드 회로를 물리적 데이터 소스(센서와 인터페이스 할 때) 및 정교한 컨트롤러(액츄에이터와 인터페이스 할 때)로 취급합니다.

 

Python에서 설계된 그래픽 인터페이스는 내장된 회로와 상호 작용하고, 센서 데이터를 시각화하고, 분석 및 의사 결정을 위한 데이터를 조작하고, 일반적으로 마이크로컨트롤러에서는 불가능한 추가 상호 작용을 제공합니다.

 

RPi 임베디드 전자 앱용 Python Tkinter GUI 예제입니다.

https://www.educba.com/python-tkinter/

 

Python에는 그래픽 사용자 인터페이스를 개발하기 위한 몇 가지 옵션이 있습니다. 가장 인기 있는 것들은 다음과 같습니다:

 

Tkinter: Tk GUI 툴킷을 위한 표준 Python 인터페이스 및 Python의 표준 사실상 GUI입니다. Tkinter는 무료이며 Linux, Microsoft Windows 및 Mac OS-X의 Python 설치에 자동으로 포함됩니다. 그러나 응용 프로그램에서 사용하려면 Tkinter 패키지를 가져와야 합니다.

 

WxPython: Python용 오픈 소스, 크로스 플랫폼 GUI 툴킷. 주요 장점은 기본 위젯(OS별 기본 위젯)입니다.

 

PyQT: 플랫폼 간 GUI 툴킷 Qt에 대한 바인딩. 아마도 파이썬을 위한 가장 강력하고 실질적인 GUI일 것입니다. PyQT는 대규모 애플리케이션에 이상적으로 적합하며 GPL 및 상용 라이선스에 따라 사용할 수 있습니다. 상업용 애플리케이션에 사용하기에는 복잡할 수 있습니다.

 

PySide: 기능면에서 PyQT와 유사하지만 PySide는 LGPL 라이선스가 적용됩니다. 따라서 상용 응용 프로그램에서 쉽게 사용할 수 있습니다.

 

Python용 GUI 패키지가 많이 있습니다. 응용 프로그램에서 on을 사용하기 전에 먼저 기능, 이식성, 개발 도구, 라이선스 및 제한 사항에 대해 배우는 것이 중요합니다. 대규모 애플리케이션 경우 PyQT와 PySide가 일반적으로 최상의 옵션입니다(그리고 PySide는 보다 자유로운 라이선스를 보유하고 있습니다).

 

PyQT 및 PySide에 사용할 수 있는 WYSIWYG 편집기도 있어 인터페이스를 빠르고 쉽게 설계할 수 있습니다. Tkinter는 기본 애플리케이션을 위한 최고의 선택입니다.

 

RPi 레시피용 GUI를 설계하기 위해 Tkinter를 사용할 것입니다. 다른 패키지에 비해 상대적으로 빠른 실행으로 작은 공간을 제공합니다. 레이아웃 관리도 매우 효율적입니다. 이러한 기능은 Tkinter를 임베디드 UI에 이상적인 옵션으로 만듭니다.

 

그러나 각 위젯에 대한 코드를 작성해야 하고 이벤트를 처리하는 것이 때때로 까다롭습니다. 이러한 노력은 작은 임베디드 앱의 속도를 높이는 것입니다.

 

멀티스레딩 임베디드 작업

 

임베디드 애플리케이션에서는 특정 작업을 반복하는 것이 일반적입니다. 예를 들어, 반복적으로 센서에서 데이터를 가져오거나 디스플레이 장치에 메시지를 표시해야 할 수 있습니다. 그러나 데스크톱 응용 프로그램에는 이러한 작업이 거의 포함되지 않습니다. 데스크톱 응용 프로그램에 대한 코드가 끝없는 무한 루프를 실행하는 것을 원하지 않을 것입니다.

 

RPi 레시피에서는 임베디드 애플리케이션의 일반적인 무한 루프를 구현할 것입니다. 그러나 GUI 앱에서 이러한 루프를 실행하면 인터페이스가 정지되고 다른 명령을 입력할 수 없습니다.

 

따라서 모든 임베디드 작업에 대해 별도의 스레드를 만들고 GUI는 Linux에서 다른 프로세스로 실행됩니다. 필요할 때마다 작업을 중지하는 작은 코딩 트릭으로 이러한 스레드를 종료하는 명령을 전달할 수 있습니다. 스레드를 사용하면 RPi 레시피를 마이크로컨트롤러 기반 임베디드 애플리케이션과 같이 처리할 수 있지만 더 효율적입니다.

 

다중 스레딩을 사용하면 여러 하드웨어 구성 요소를 동시에 독립적으로 처리할 수 있는 이점도 있습니다. 마이크로컨트롤러에서는 멀티스레딩이 불가능하며, 이는 임베디드 OS를 실행하는 SBC가 핵심임을 보여주기 위한 것입니다.

 

Tkinter 배우기

 

소개: Tkinter는 Tcl/Tk에 대한 파이썬 Wrapper로서 Tcl/Tk를 파이썬에 사용할 수 있도록 한 Lightweight GUI 모듈입니다. Tcl은 Tool Command Language의 약자로서 일종의 프로그래밍 언어이며, Tk는 크로스 플랫폼에 사용되는 GUI 툴킷입니다. Tkinter는 타 GUI 프레임워크나 툴킷에 비해 지원되는 위젯들이 부족하고 UI도 그렇게 예쁘지 않다는 단점이 있지만, Python 설치 시 기본적으로 내장되어 있는 파이썬 표준 라이브러리이기 때문에 쉽고 간단한 GUI 프로그램을 만들 때 활용될 수 있습니다. 여기서는 Python 3.4에 있는 Tkinter를 사용하며, Tkinter의 기본적인 개념 및 기초 사용법 만을 소개하고 직접 코드를 입력하면서 배우기로 합니다. 

 

Tkinter는 Python용 표준 GUI 라이브러리입니다. Tk GUI 툴킷에 객체 지향 인터페이스를 제공합니다. 모든 GUI는 레이블, 텍스트 상자, 버튼, 라디오 버튼, 선택 버튼, 캔버스 등과 같은 다양한 그래픽 요소가 배치된 기본 창으로 구성됩니다.

 

기본 창 및 기타 창을 포함한 이러한 그래픽 요소를 위젯이라고 합니다. 버튼 클릭, 텍스트 상자에 초점 맞추기, 라디오 버튼 선택 등과 같은 사용자 작업을 이벤트라고 합니다. 이벤트에 대한 응답으로 다른 창을 열 수 있으며 이 창을 부모 창에 대한 자식 창이라고 합니다.

 

Tkinter는 파이썬에 기본 내장되어 있기 때문에 PyQt처럼 별도로 설치할 필요가 없습니다. Tkinter를 사용하기 위해서는 먼저 tkinter 모듈을 아래와 같이 import 해야 합니다. (주: Python 2에서는 Tkinter를 import 하고, Python 3 에서는 tkinter를 import 한다). tkinter 모듈을 import 한 다음에는 Tk 클래스 객체(root)를 생성하고, 이 객체의 mainloop() 메서드를 호출한다. 아래 코드와 같이 이런 기본 문장들을 수행하면, 빈 다이얼로그가 화면에 표시된다. 아래 코드를 first-window.py로 저장을 하고 실행은 $python3 first-window.py 명령으로 실행한다.

 

from tkinter import *
root = Tk()
root.mainloop()

실행하면 빈 윈도 화면이 썰렁하게 보입니다. 

 

처음 GUI

 

다음은 Python 3에서 Tkinter 모듈을 가져오기 위한 유효한 명령문입니다.

 

import tkinter
or
from tkinter import *
or
import tkinter as tk

 

위의 세 번째 예에서 "tk"는 Tk 클래스에 대해 정의된 참조입니다. 이 참조는 모든 식별자가 될 수 있습니다. Tkinter 모듈을 가져온 후 GUI 응용 프로그램 메인 창을 만듭니다. 이것은 Tk 클래스의 인스턴스 객체를 생성하여 수행할 수 있습니다. 기본 창(다른 창의 자식이 아님)의 경우 인수 없이 Tk 개체가 생성됩니다.

 

다음은 기본 창을 만들기 위한 유효한 명령문입니다.

 

root = Tk()
or
root = tkinter.Tk()
or
root = tk.Tk() # tk is reference to Tk() class in the import statement

 

자식 창을 만들려면 먼저 Toplevel() 메서드를 사용하여 인스턴스 개체를 만들어야 합니다. 이 개체는 부모 창(객체)에 인수로 전달되어야 합니다.

 

다음은 자식 창을 만들기 위한 유효한 명령문입니다.

 

LED_window = Toplevel(root)

 

기본 창을 포함한 모든 창 위젯은 여러 가지 방법을 지원합니다. 모든 메서드 중에서 mainloop() 메서드가 가장 중요합니다. mainloop()는 이벤트 메시지 루프로서 키보드나 마우스 혹은 화면 Redraw와 같은 다양한 이벤트로부터 오는 메시지를 받고 전달하는 역할을 합니다.

 

창 위젯에서 mainloop() 메서드가 호출될 때까지는 화면에 나타나지 않습니다. mainloop() 메서드는 무한 루프를 시작하여 GUI 창을 실행하고 이벤트가 발생할 때까지 기다렸다가 창이 닫히지 않는 한 이벤트를 처리합니다.

 

따라서 mainloop() 메서드는 창 위젯에서 호출되는 마지막 명령문이어야 합니다. mainloop() 이후에 위젯에서 호출된 다른 메서드는 실행되지 않고 오류를 반환합니다.

 

다음은 Tkinter에서 기본 창을 시작하는 코드입니다.

 

root = Tk()
root.mainloop()

 

다음은 자식 윈도를 시작하는 코드입니다.

 

LED_window = Toplevel(root)
LED_window.mainloop()

 

destroy() 메서드를 호출하여 창을 파괴할 수 있습니다. 다음은 창(이름이 지정된 창)을 파괴하는 유효한 명령문입니다.

 

window.destroy()

 

윈도 스타일과 동작은 다른 메서드를 호출하여 변경할 수 있습니다. 예를 들어 윈도 제목을 설정하기 위해 title() 메서드를 사용할 수 있습니다. 아래는 윈도(이름이 지정된 창) 제목을 설정하는 코드입니다.

 

window.title(“Raspberry Pi 제어 앱”)

 

화면에서 윈도 크기와 위치를 설정하려면 geometry() 메서드를 사용할 수 있습니다. 기하학 방법은 다음과 같이 4개의 선택적 인수를 사용할 수 있습니다.

 

window.geometry(“widthxhieght+/-horizontal_position+/-vertical_position”)

 

이것은 윈도(이름이 지정된 창) 크기와 위치를 설정하기 위한 유효한 명령문입니다.

 

window.geometry(“300×300+100+50”)

 

네 가지 인수(window 너비, window 높이, 수평 위치 및 수직 위치)는 모두 픽셀 단위 정수 값을 허용합니다.

 

기술 노트:

 

  • 수평 위치에 선행 더하기 기호가 있는 경우 창의 왼쪽 가장자리는 화면 왼쪽 가장자리에서 떨어진 픽셀만큼입니다.
  • 수평 위치에 앞에 - 기호가 있는 경우 창의 오른쪽 가장자리는 화면의 오른쪽 가장자리에서 떨어진 픽셀만큼입니다.
  • 유사하게, 수직 ​​위치에 + 기호가 있는 경우 창의 상단 가장자리는 화면 상단 가장자리로부터 많은 픽셀이 되며 수직 위치에 - 기호가 있는 경우 창의 하단 가장자리는 그 수만큼의 픽셀이 됩니다. 화면 하단 가장자리에서 시작합니다.

minsize() 및 maxsize() 메서드를 사용하여 window 최소 및 최대 크기를 설정할 수도 있습니다. 두 방법 모두 window 너비와 높이를 픽셀 단위로 인수로 사용합니다. 다음은 창(이름이 지정된 창)의 최소 크기를 설정하는 코드입니다.

 

window.minsize(480, 480)

 

기본적으로 window 크기를 조정할 수 있으며 사용자는 window 가장자리를 끌어 크기를 변경할 수 있습니다. window 크기 조정 동작은 resizable() 메서드를 사용하여 변경할 수 있습니다.

 

이 메서드는 두 개의 부울 인수를 사용하여 크기를 조정할 수 있는 window 너비와 높이를 True 또는 False로 설정합니다.

 

Tkinter 모듈은 또한 정적 인터페이스를 생성할 수 있습니다. 사용자가 window 크기를 조정할 때 인터페이스의 정적 특성으로 인해 레이아웃이 어색해질 수 있습니다. 따라서 다음과 같이 window 크기 조정 기능을 False로 설정하는 것이 좋습니다.

 

window.resizable(False, False)

 

창은 포함된 자식 위젯에 따라 자동으로 크기가 조정됩니다. window 최대 크기가 설정된 경우 일부 하위 위젯이 표시되지 않을 수 있습니다. 따라서 윈도 최대 크기를 설정하지 않는 것이 좋습니다. 윈도는 다음과 같은 여러 상태를 가질 수 있습니다.

 

  • Normal – 기본 크기와 위치로 화면에 표시
  • Zoomed- 전체 화면을 덮고 표시됨
  • Icon – 작업 표시줄로 최소화
  • Withdraw – 창 닫힘

기본적으로 창은 "정상" 상태로 나타납니다. 가로, 세로 모두 크기 조정이 설정되어 있는 경우 최대화 버튼을 클릭하여 전체 화면 크기로 확대할 수 있습니다. 다음과 같은 상태로 설정하여 코드 내에서 "확대"할 수도 있습니다.

 

window.state(‘zoomed’)

 

최소화 버튼을 클릭하여 창을 아이콘으로 최소화할 수 있습니다. iconify() 메서드를 사용하거나 다음과 같이 상태를 'icon'으로 설정하여 코드 내에서 아이콘으로 최소화할 수 있습니다.

 

window.state('icon') 또는 window.iconify()

 

작업 표시줄에서 해당 아이콘을 클릭하여 창을 정상 상태로 복원할 수 있습니다. deiconify() 메서드를 사용하거나 상태를 "정상"으로 설정하여 코드 내에서 정상 상태로 복원할 수 있습니다.

 

window.state(‘normal’) 또는 window.deiconify()

 

GUI 창에서 ttk 테마 위젯을 사용할 것입니다. ttk는 Tk 테마 위젯에 대한 액세스를 제공하는 별도 모듈입니다. 위젯 모양을 구현하는 코드와 위젯 동작을 구현하는 코드를 구분합니다.

 

이것은 Tkinter와 별도로 ttk를 가져와야 함을 의미합니다. 다음은 ttk를 가져오기 위한 유효한 코드입니다.

 

import ttk
or
from ttk import *
or
from tkinter import ttk
The following are valid statements to start a blank main window:
from tkinter import *
from tkinter import ttk
root = Tk()
root.title(“RPi Embedded Electronics Control APP”)
root.minsize(480, 480)
root.resizable(0, 0)
root.mainloop()

 

이것은 다른 위젯을 포함하지 않는 빈 GUI 기본 창입니다. mainloop() 메서드는 기본 window 구문 마지막 문에서 호출됩니다. 실행화면은 아래와 같습니다.

 

 

 

이제 Raspberry Pi를 사용하여 임베디드 애플리케이션에 대한 다중 스레딩 접근 방식을 목격하게 될 것입니다. 단일 보드 컴퓨터에서 마이크로 컨트롤러 방식의 임베디드 작업을 구현하면서 데스크톱 GUI 앱을 통해 임베디드 회로를 제어합니다.

 

다음 튜토리얼에서 라즈베리파이 임베디드 전자 제어 응용 프로그램에 메뉴를 추가하고 Tkinter와 TTK 위젯에 대한 자세한 내용을 알아보겠습니다. 또한 앱에서 제어되는 모든 임베디드 전자 부품(디스플레이 장치, 센서, 모듈, 모터 및 통신 인터페이스)에 대해 GUI 프레임을 앱에 계속 추가할 것입니다. 기대하세요. 

 

빛깔 참 곱다.

 

 

 

반응형