5
edits
(22 intermediate revisions by 12 users not shown) | |||
Line 1: | Line 1: | ||
{{Template: | {{Template:바로 가기}} | ||
<div style="float: right; margin-left: 12px">__TOC__</div> | <div style="float: right; margin-left: 12px">__TOC__</div> | ||
[[Tkinter]] [[패키지]]는 Tk GUI [[툴킷]]([[toolkit]])에 대한 [[파이썬]]([[Python]])의 표준 인터페이스이다. Tkinter는 Tk interface의 줄임말로 [[트킨터]] 또는 [[티케이인터]]라고 읽는다. ttk나 messagebox같은 [[모듈]]을 모아놓은 것을 Tkinter [[package]]라고 한다 | [[트킨터]] ([[Tkinter]]) [[패키지]]는 Tk GUI [[툴킷]]([[toolkit]])에 대한 [[파이썬]]([[Python]])의 표준 인터페이스이다. Tkinter는 Tk interface의 줄임말로 [[트킨터]] 또는 [[티케이인터]]라고 읽는다. ttk나 messagebox같은 [[모듈]]을 모아놓은 것을 Tkinter [[package]]라고 한다. | ||
[[Tk]]는 플랫폼 독립적인 [[GUI]] 라이브러리이다. [[티케이]]는 많은 [[프로그래밍 언어]]에서 [[그래픽 유저 인터페이스]](GUI)를 만들기 위한 GUI [[위젯]](widget)의 기본 요소들의 [[라이브러리]](library)를 제공하는 [[오픈 소스]] [[크로스 플랫폼]] 위젯 툴킷이다. | [[Tk]]는 플랫폼 독립적인 [[GUI]] 라이브러리이다. [[티케이]]는 많은 [[프로그래밍 언어]]에서 [[그래픽 유저 인터페이스]](GUI)를 만들기 위한 GUI [[위젯]](widget)의 기본 요소들의 [[라이브러리]](library)를 제공하는 [[오픈 소스]] [[크로스 플랫폼]] 위젯 툴킷이다. | ||
Line 9: | Line 9: | ||
[[Tcl]]과 [[Tk]] GUI 툴킷을 묶어서 Tcl/Tk라고 부른다. | [[Tcl]]과 [[Tk]] GUI 툴킷을 묶어서 Tcl/Tk라고 부른다. | ||
이 [[문서]]의 [[쏠쓰 코드]] ([[source code]])는 [[우분투]] 19.10, [[파이썬]] 3.7.5에서 테스트되었다. | |||
Line 20: | Line 24: | ||
[[ | [[우분투]] 19.10에는 python3-tk 패키지가 설치되어있지 않으므로 [[터미널]] ([[terminal]])에서 | ||
sudo apt | sudo apt install python3-tk | ||
[[명령어]] ([[command]])를 입력하여 관련 패키지를 설치해준다. | |||
[[소스 코드]] [[편집기]]로는 [[VS코디엄]] ([[VSCodium]])이나 적당히 아무거나 쓰면 된다. | |||
우분투 19.10의 경우 | |||
python3 cal.py | |||
와 같은 방식으로 실행시키면 된다. | |||
= pack, grid로 부품 배열 = | == pack, grid로 부품 배열 == | ||
박스 띄우기 | 박스 띄우기 | ||
Tk()는 트킨터 객체의 생성자이다. | Tk()는 트킨터 객체의 생성자이다. | ||
root=Tk() | root=Tk() | ||
를 | 를 입력하면 빈 창이 뜬다. | ||
(Tk객체).mainloop()를 하면 창에서 입력을 받아들인다. | (Tk객체).mainloop()를 하면 창에서 입력을 받아들인다. | ||
root.mainloop() | |||
와 같이 해주면 된다. | |||
from tkinter import * | |||
root=Tk() | |||
root.mainloop() | root.mainloop() | ||
까지 최소 3줄을 [[쏠쓰 코드]] ([[source code]])에 포함해줘야 빈 창이 뜬다. | |||
위젯(widget) 달기 | 위젯(widget) 달기 | ||
pussy = widget_name(new_Tk_object, ... ) | |||
pussy.pack() | |||
와 같은 방식으로 달아줄 수 있다. | 와 같은 방식으로 달아줄 수 있다. pussy는 임의로 붙인 명칭이다. | ||
Line 50: | Line 70: | ||
root = Tk() | root = Tk() | ||
sister_pussy = Label(root, text = "sis pussy") | |||
sister_pussy.pack() | |||
sister_pussy는 임의로 붙인 명칭이다. 그러나 "Label"은 반드시 그대로 써야한다. | |||
Line 67: | Line 87: | ||
== 레이블 1개, 입력 창 1개, 버튼 2개 == | |||
아래는 grid로 만들어본 상자이다. (기능은 | 완성된 [[코드]] ([[code]])는 아래와 같다. | ||
from tkinter import * | |||
root = Tk() | |||
sister_pussy = Label(root, text = "sis pussy") | |||
sister_pussy.pack() | |||
root.mainloop() | |||
=== 레이블 1개, 입력 창 1개, 버튼 2개 === | |||
아래는 grid로 만들어본 상자이다. (기능은 없다.) | |||
from tkinter import * | from tkinter import * | ||
root = Tk() | root = Tk() | ||
title = Label(root,text=" | title = Label(root,text="Input") | ||
txtbox = Entry(root, width = 15) | txtbox = Entry(root, width = 15) | ||
btn_1= Button(root, text = " | btn_1= Button(root, text = "Submit", width=10) | ||
btn_2 = Button(root, text = " | btn_2 = Button(root, text= "Cancel", width=10) | ||
title.grid(row=0, column=0) | title.grid(row=0, column=0) | ||
txtbox.grid(row=0,column=1) | txtbox.grid(row=0, column=1) | ||
btn_1.grid(row=1,column=1) | btn_1.grid(row=1,column=1) | ||
btn_2.grid(row=2,column=1) | btn_2.grid(row=2, column=1) | ||
root.mainloop() | root.mainloop() | ||
Line 94: | Line 126: | ||
btn_2.grid(row=1,column=1) | btn_2.grid(row=1,column=1) | ||
* tkinter 처음하기 | * tkinter 처음하기 https://studioplug.tistory.com/219 | ||
== 레이블 2개, 입력 창 2개 == | === 레이블 2개, 입력 창 2개 === | ||
Grid라고 하는 geometry manager는 위젯을 2차원의 표에 놓습니다. | Grid라고 하는 geometry manager는 위젯을 2차원의 표에 놓습니다. | ||
마스터위젯은 row와 column에 해당하는 숫자로 나뉘고, 완성된 표에서 각각의 '셀'(표의 한 칸)은 위젯을 잡아둡니다. | 마스터위젯은 row와 column에 해당하는 숫자로 나뉘고, 완성된 표에서 각각의 '셀'(표의 한 칸)은 위젯을 잡아둡니다. | ||
Line 147: | Line 179: | ||
위와 같이 sticky 옵션을 쓰지 않으면 위젯들이 각각의 셀(cell)에서 가운데 정렬된다. sticky 옵션은 N,S,E,W 중에 하나 이상의 값을 필요로 합니다. 레이블(label)들을 왼쪽정렬하기 위해, sticky=W를 사용합니다. N = north 북족, W = west 서쪽, E = east 동쪽, S = south 남쪽. | 위와 같이 sticky 옵션을 쓰지 않으면 위젯들이 각각의 셀(cell)에서 가운데 정렬된다. sticky 옵션은 N,S,E,W 중에 하나 이상의 값을 필요로 합니다. 레이블(label)들을 왼쪽정렬하기 위해, sticky=W를 사용합니다. N = north 북족, W = west 서쪽, E = east 동쪽, S = south 남쪽. | ||
=== 체크 박스와 그림 추가 === | ==== 체크 박스와 그림 추가 ==== | ||
from tkinter import * | from tkinter import * | ||
master = Tk() | master = Tk() | ||
Line 205: | Line 237: | ||
자세한 내용은 아래 링크 참조 | 자세한 내용은 아래 링크 참조 | ||
* tkinter grid method | * tkinter grid method https://studioplug.tistory.com/220 | ||
== 체크버튼, 콤보박스 넣기 == | |||
= 체크버튼, 콤보박스 넣기 = | === 레이블 안에 이미지 넣기 === | ||
== 레이블 안에 이미지 넣기 == | |||
1. Tkinter 위젯 | 1. Tkinter 위젯 | ||
Line 275: | Line 306: | ||
main() | main() | ||
예제로 배우는 파이썬 프로그래밍 - Tkinter 위젯 | 예제로 배우는 파이썬 프로그래밍 - Tkinter 위젯 https://pythonstudy.xyz/python/article/121-Tkinter-%EC%9C%84%EC%A0%AF | ||
== 체크버튼 == | === 체크버튼 === | ||
checkbutton 위젯 체크버튼 | checkbutton 위젯 체크버튼 | ||
Line 358: | Line 389: | ||
== 텍스트박스 == | === 텍스트박스 === | ||
textbox 위젯 | textbox 위젯 | ||
Line 398: | Line 429: | ||
== 콤보박스 == | === 콤보박스 === | ||
combobox 위젯 | combobox 위젯 | ||
Line 449: | Line 480: | ||
== 버튼 클릭시 새 창 띄우기 == | === 버튼 클릭시 새 창 띄우기 === | ||
from tkinter import * | from tkinter import * | ||
Line 519: | Line 550: | ||
== 프레임 여러개 만들기 == | === 프레임 여러개 만들기 === | ||
아래 예제는 고객 데이타를 입력 받는 간단한 윈도우 샘플이다. 메인 Frame 안에 4개의 자식 Frame을 사용하였고, 각각의 자식 Frame 안에 레이블, 텍스트, 버튼 등의 위젯들을 추가하였다. | 아래 예제는 고객 데이타를 입력 받는 간단한 윈도우 샘플이다. 메인 Frame 안에 4개의 자식 Frame을 사용하였고, 각각의 자식 Frame 안에 레이블, 텍스트, 버튼 등의 위젯들을 추가하였다. | ||
Line 580: | Line 611: | ||
main() | main() | ||
예제로 배우는 파이썬 프로그래밍 - Tkinter 위젯 | 예제로 배우는 파이썬 프로그래밍 - Tkinter 위젯 https://pythonstudy.xyz/python/article/121-Tkinter-%EC%9C%84%EC%A0%AF | ||
= | === 체크버튼과 입력값으로 if문 만들기 === | ||
from tkinter import * | |||
from tkinter import ttk, messagebox | |||
class cframe: | |||
def __init__(self, fr): | |||
self.defframe = fr | |||
self.fr0 = Frame(fr) | |||
self.fr0.pack() | |||
global virgin, bitch, price, rent | |||
virgin = IntVar() | |||
bitch = IntVar() | |||
price = IntVar() | |||
rent = IntVar() | |||
self.fr1 = Frame(self.fr0) | |||
self.fr1.pack(fill=X) | |||
imgplace = PhotoImage(file = '로리공주.gif') | |||
self.la1 = Label(self.fr1, image = imgplace) | |||
self.la1.image = imgplace | |||
self.la1.pack() | |||
self.fr2 = Frame(self.fr0) | |||
self.fr2.pack(fill = X) | |||
self.la2 = Label(self.fr2, text = "처녀막이 있다고 생각함?") | |||
self.la2.pack(side = LEFT) | |||
self.cb2_2 = Checkbutton(self.fr2, text = '걸레', variable = bitch) | |||
self.cb2_2.pack(side = RIGHT) | |||
self.cb2_1 = Checkbutton(self.fr2, text = '처녀', variable = virgin) | |||
self.cb2_1.pack(side = RIGHT) | |||
self.fr3 = Frame(self.fr0) | |||
self.fr3.pack(fill=X) | |||
self.la3 = Label(self.fr3, text = "산다면 얼마까지 낼 생각?(가격은 백만원 단위로)") | |||
self.la3.pack(side = LEFT) | |||
self.en3 = Entry(self.fr3, textvariable = price) | |||
self.en3.pack(side = RIGHT) | |||
self.fr4 = Frame(self.fr0) | |||
self.fr4.pack(fill=X) | |||
self.la4 = Label(self.fr4, text = "남한테 빌려준다면 얼마에 빌려줄래?(가격은 백만원 단위로)") | |||
self.la4.pack(side = LEFT) | |||
self.en4 = Entry(self.fr4, textvariable = rent) | |||
self.en4.pack(side = RIGHT) | |||
self.fr5 = Frame(self.fr0) | |||
self.fr5.pack(fill=X) | |||
self.bu5_1 = ttk.Button(self.fr5, text = "입찰", command=cframe.selection) | |||
self.bu5_1.pack(side = LEFT) | |||
self.bu5_2 = ttk.Button(self.fr5, text = "포기", command=cframe.cbutton) | |||
self.bu5_2.pack(side = RIGHT) | |||
def selection(): | |||
stringv = <nowiki>''</nowiki> | |||
if virgin.get() == 1 and bitch.get() == 1: | |||
stringv = "어떻게 처녀면서 걸레지?" | |||
elif virgin.get() == 1: | |||
if price.get() < 100: | |||
stringv = "처녀에 이정도 미인을 1억원도 안 내고 사려고?" | |||
if rent.get() > 10: | |||
stringv = stringv + " 1억도 안 주고 산 걸 천만원 넘게 받고 빌려주다니 개새끼네." | |||
else: | |||
stringv = stringv + " 1억도 투자 안 했으니까 싸게라도 많이 굴리면 본전은 뽑겠지!" | |||
elif 100 <= price.get() <= 1000: | |||
stringv = "이렇게 예쁜데다 처녀 공주인데 몇억은 내야지!" | |||
if rent.get() < 10: | |||
stringv = stringv + " 몇억 주고 산 처녀를 천만원도 안 되는 돈에 빌려주다니 제정신?" | |||
else: | |||
stringv = stringv + ' 몇억짜리 처녀인데 천만원은 넘게 받아야 빌려주지.' | |||
else: | |||
stringv = "아무리 처녀라도 10억원 이상을 내다니 미쳤네." | |||
elif bitch.get() == 1: | |||
if price.get() > 100: | |||
stringv = "걸레한테 1억원을 넘게 내다니 미쳤구나!" | |||
if rent.get() < 1: | |||
stringv = stringv + ' 아무리 걸레라도 원래 공주였는데 고작 100만원도 안 받고 빌려준다니 완전 너덜너덜해질 때까지 굴릴 생각?' | |||
else: | |||
stringv = stringv + ' 원래 공주였는데 이정도는 받아야 빌려주지.' | |||
elif 100 >= price.get() >= 10: | |||
stringv = '걸레 몸값으로는 이게 적정가지.' | |||
if rent.get() < 1: | |||
stringv = stringv + ' 걸레인데 창녀로 굴리면서 화대로 100만원씩이나 받을 수는 없지.' | |||
else: | |||
stringv = stringv + ' 명색이 공주인데 화대로 백만원은 받아야 하지 않겠어?' | |||
else: | |||
stringv = "예뻐도 비처녀라면 좀..." | |||
if rent.get() < 0.1: | |||
stringv = stringv + ' 아무리 천만원도 안 주고 산 여자라고 해도 1회 십만원도 안 받고 빌려줄수가 있냐?' | |||
else: | |||
stringv = stringv + ' 비싼 보지가 왔어요! 한 번 쑤시는데 10만원 넘게 듭니다!' | |||
else: | |||
stringv = "처녀가 아니면서 걸레도 아니라고?" | |||
messagebox.showinfo("경매 결과", stringv) | |||
def cbutton(): | |||
mwin.destroy() | |||
mwin = Tk() | |||
mwin.title('노예 시장에 매물로 나온 공주') | |||
mwin.geometry("620x420+290+160") | |||
cfview = cframe(mwin) | |||
mwin.mainloop() | |||
체크버튼과 엔트리(Entry)로 값을 입력 받은 후 그 값을 if, elif, else문에 넣어 각각의 조건에 해당하는 문장을 새 창에 출력한다. 하나의 조건에 하나의 문장을 배당하고, 2개의 값의 조합에 2개의 문장이 조합되어 출력된다. | |||
로리공주.gif 파일을 이 파이썬 프로그램과 같은 폴더에 넣어놓거나, 이미지 파일의 위치를 절대 경로나 상대 경로로 적어주어야 한다. 파일의 이름은 바뀌어도 되나 반드시 gif 파일이어야 하며 jpg나 png 파일은 쓸 수 없다. | |||
== packing 하기 == | |||
절대 경로는 /home/username/사진/로리공주.gif 같은 것이나 D:\사진\로리공주.gif 같은 것이고, 상대 경로는 ./사진/로리공주.gif 나 .\사진\로리공주.gif 같은 것이다. [[유닉스]]와 [[리눅스]]에서는 [[디렉터리]] 구분을 [[슬래시]](/)로 하고, [[윈도우즈]]에서는 [[역슬래시]](\)나 [[원화]] 기호(₩)로 한다. 리눅스나 윈도우즈 모두 현재 폴더는 .으로 나타내며 상위 폴더는 ..으로 나타낸다. username 폴더에 해당하는 사용자의 홈 디렉터리는 ~로 표시한다. 루트(/)나 드라이브 문자(D:)처럼 최상위 경로부터 적는 것을 절대 경로라고 하고, 중간을 생략하고 현재 디렉터리 기준으로 적는 것을 상대 경로라고 한다. | |||
즉, 이미지 파일이 이 파이썬 프로그램이 있는 폴더의 하위 폴더인 "사진" 폴더에 있을 경우 imgplace = PhotoImage(file = './사진/로리공주.gif') 와 같은 식으로 적어주면 된다. 다른 곳에서도 이 프로그램을 수정 없이 쓰기 위해서는 절대 경로로 적는 것은 피하고, 되도록이면 상대 경로로 적어줘야 한다. 이미지 파일이 1,000개쯤 된다고 생각해봐라. 이걸 다 수정하는 노가다를 하느니 처음부터 상대 경로로 적어주는 것이 좋다. 이미지 파일 뿐만 아니라 다른 파일의 경우도 마찬가지이다. 특히 [[웹 싸이트]] 만들 때 로컬 컴퓨터에서 개발할 때랑 [[가상 전용 써버]]([[VPS]])에 업로드 할 때랑 절대 경로가 다르므로 문제가 생기는 경우가 많다. 개발할 때부터 상대 경로만 쓰면 VPS에 그대로 업로드해도 잘 작동한다. | |||
== 객체 지향 프로그래밍(클래스 사용) == | |||
[[파이썬]]에서는 [[클래스]](class)를 사용하여 [[객체 지향 프로그래밍]](object-oriented programming, OOP)을 할 수 있다. | |||
* Python,tkinter 입문 (Python, tkinter 간단히 사용하기 001) https://blog.naver.com/dudwo567890/130166663839 | |||
=== 아무 것도 없는 창 === | |||
from tkinter import * | |||
root=Tk() | |||
root.mainloop() | |||
위에서 생성된 최상위창은 tkinter 애플리케이션에서 가장 높은 수준의 GUI구성요소이며, 최상위 창의 이름은 'root'로 하는것이 관례적이다. | |||
=== packing 하기 === | |||
아래 예제에서 tkinter 프로그래밍의 세가지 주요 개념이 나온다. | 아래 예제에서 tkinter 프로그래밍의 세가지 주요 개념이 나온다. | ||
Line 623: | Line 781: | ||
즉, 애플리케이션에 보여지도록 설정한다. | 즉, 애플리케이션에 보여지도록 설정한다. | ||
== 창 부품(위젯) 꾸리기 == | === 창 부품(위젯) 꾸리기 === | ||
창 가운데 녹색 버튼 띄우기. | 창 가운데 녹색 버튼 띄우기. | ||
Line 656: | Line 814: | ||
즉, root의 자식은 F이며, F의 자식은 button1이 되는것이다. | 즉, root의 자식은 F이며, F의 자식은 button1이 되는것이다. | ||
== 클래스 구조 == | === 클래스 구조 === | ||
왜 애플리케이션을 클래스로 구성하는가? | 왜 애플리케이션을 클래스로 구성하는가? | ||
Line 680: | Line 838: | ||
root.mainloop() | root.mainloop() | ||
=== 중앙에 닫기 버튼이 있는 창 === | ==== 중앙에 닫기 버튼이 있는 창 ==== | ||
import tkinter as tk | import tkinter as tk | ||
class Application(tk.Frame): | class Application(tk.Frame): | ||
Line 696: | Line 854: | ||
창이 작게 뜨기 때문에 창 맨 위에 뜨는 제목(title)인 "니 [[애미]] 보지"가 보이지 않는다. 마우스로 창을 키우면 창 이름인 "니 애미 [[보지]]"가 보인다. | 창이 작게 뜨기 때문에 창 맨 위에 뜨는 제목(title)인 "니 [[애미]] 보지"가 보이지 않는다. 마우스로 창을 키우면 창 이름인 "니 애미 [[보지]]"가 보인다. | ||
== 속성 설정하기 == | === 속성 설정하기 === | ||
from tkinter import * | from tkinter import * | ||
Line 735: | Line 893: | ||
또 한 가지 주목할 점은 버튼을 추가한 순서대로 차곡차곡 쌓이며 보여지는것을 알수 있다. | 또 한 가지 주목할 점은 버튼을 추가한 순서대로 차곡차곡 쌓이며 보여지는것을 알수 있다. | ||
== 정렬 == | === 정렬 === | ||
packing은 구성요소의 시각적 관계를 제어하는 방법이다. | packing은 구성요소의 시각적 관계를 제어하는 방법이다. | ||
Line 795: | Line 953: | ||
복잡한 GUI를 다루는 방법으로 여러 동선을 사용하고 싶을땐, 그릇안에 그릇을 내포시키는 것이다. | 복잡한 GUI를 다루는 방법으로 여러 동선을 사용하고 싶을땐, 그릇안에 그릇을 내포시키는 것이다. | ||
== 사건 묶기 == | === 사건 묶기 === | ||
사건묶기(binding)이란 다음과 같은 객체들 사이의 관계 또는 연결을 정의하는 과정이다. | 사건묶기(binding)이란 다음과 같은 객체들 사이의 관계 또는 연결을 정의하는 과정이다. | ||
Line 879: | Line 1,037: | ||
이런식으로 동작하려면 myapp은 자신의 자손이 누구인지 알아야 한다. 그래서 5행에서 myapp이 그의 부모를 기억하도록 한것이다. | 이런식으로 동작하려면 myapp은 자신의 자손이 누구인지 알아야 한다. 그래서 5행에서 myapp이 그의 부모를 기억하도록 한것이다. | ||
== 초점(focus) == | === 초점(focus) === | ||
위의 예제에서는 마우스로 클릭하면 버튼에게 일을 시킬 수 있었다. | 위의 예제에서는 마우스로 클릭하면 버튼에게 일을 시킬 수 있었다. | ||
Line 983: | Line 1,141: | ||
Key 이벤트가 발생한 위젯 | Key 이벤트가 발생한 위젯 | ||
=== 키보드 입력을 보여주기 === | ==== 키보드 입력을 보여주기 ==== | ||
아래 예제는 Key 이벤트에 대해 keyPressed() 함수를 바인딩하고, 전달된 event.char 를 써서 눌려진 키를 프린트하는 코드이다. | 아래 예제는 Key 이벤트에 대해 keyPressed() 함수를 바인딩하고, 전달된 event.char 를 써서 눌려진 키를 프린트하는 코드이다. | ||
Line 1,004: | Line 1,162: | ||
root.mainloop() | root.mainloop() | ||
예제로 배우는 파이썬 프로그래밍 - Tkinter 이벤트 | 예제로 배우는 파이썬 프로그래밍 - Tkinter 이벤트 https://pythonstudy.xyz/python/article/122-Tkinter-%EC%9D%B4%EB%B2%A4%ED%8A%B8 | ||
== 명령어 묶기 == | === 명령어 묶기 === | ||
명령어 묶기(Command Binding) | 명령어 묶기(Command Binding) | ||
Line 1,071: | Line 1,229: | ||
즉, 버튼자체에 명령어를 묶어주는것을 명령어 묶기 라고 할수 있다. | 즉, 버튼자체에 명령어를 묶어주는것을 명령어 묶기 라고 할수 있다. | ||
== 사건묶기와 명령어묶기의 차이 == | === 사건묶기와 명령어묶기의 차이 === | ||
바로 위 예제에서는 Tab키를 이용하여 초점을 "OK"버튼창부품에 두고, 스페이스바를 눌러서 버튼색이 바뀌도록 할수는 있지만, 엔터키를 투르면 아무 효과도 없다. | 바로 위 예제에서는 Tab키를 이용하여 초점을 "OK"버튼창부품에 두고, 스페이스바를 눌러서 버튼색이 바뀌도록 할수는 있지만, 엔터키를 투르면 아무 효과도 없다. | ||
Line 1,148: | Line 1,306: | ||
사건묶기는 원하는 사건에 원하는 사건처리자를 연결하여 창부품에 지정하는것이라고 할수 있다. | 사건묶기는 원하는 사건에 원하는 사건처리자를 연결하여 창부품에 지정하는것이라고 할수 있다. | ||
== 정보 공유하기 == | === 정보 공유하기 === | ||
지난 예제들에서는 사건처리자에게 실제로 일을 시키는 방법들을 알아보았다. | 지난 예제들에서는 사건처리자에게 실제로 일을 시키는 방법들을 알아보았다. | ||
Line 1,254: | Line 1,412: | ||
print("Complete...") | print("Complete...") | ||
== 명령어 묶기 더 자세히 == | === 명령어 묶기 더 자세히 === | ||
명령어묶기에 대하여 좀더 고급특징을 알아보도록 하겠다. | 명령어묶기에 대하여 좀더 고급특징을 알아보도록 하겠다. | ||
Line 1,323: | Line 1,481: | ||
위 예제의 문제의 해결방법을 아래예제를 통해 알아보도록 하겠다. | 위 예제의 문제의 해결방법을 아래예제를 통해 알아보도록 하겠다. | ||
== 역호출 함수 == | === 역호출 함수 === | ||
위 예제의 문제점을 살펴보면, 함수가 어플리케이션이 실행되기도 전에 ButtonHandler사건처리자가 실행된다는것이다. | 위 예제의 문제점을 살펴보면, 함수가 어플리케이션이 실행되기도 전에 ButtonHandler사건처리자가 실행된다는것이다. | ||
Line 1,437: | Line 1,595: | ||
람다(lambda)를 이용하여 인자를 전달함으로써 함수호출이 아닌 함수객체를 전달하였다. | 람다(lambda)를 이용하여 인자를 전달함으로써 함수호출이 아닌 함수객체를 전달하였다. | ||
== 함수 내포 기법(currying) == | === 함수 내포 기법(currying) === | ||
앞의 예제에서 인자를 사건처리자(함수)에 건네기 위해 람다를 사용한 방법을 알아보았다. | 앞의 예제에서 인자를 사건처리자(함수)에 건네기 위해 람다를 사용한 방법을 알아보았다. | ||
Line 1,450: | Line 1,608: | ||
자세한 내용은 아래URL에서 알수 있다. | 자세한 내용은 아래URL에서 알수 있다. | ||
https://aspn.activestate.com/ASPN/Python/Cookbook/ | |||
https://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549 | |||
Line 1,575: | Line 1,733: | ||
단점은 이것들을 사용하기 위해서는 프로그램에 코드를 삽입해주어야 한다는것이다. | 단점은 이것들을 사용하기 위해서는 프로그램에 코드를 삽입해주어야 한다는것이다. | ||
>대조적으로 lambda는 파이썬에 내장되어 있다. 반입하기 위해 특별히 해야 할것이 없다. | >대조적으로 lambda는 파이썬에 내장되어 있다. 반입하기 위해 특별히 해야 할것이 없다. | ||
Line 1,581: | Line 1,738: | ||
단점은 lambda를 사용하면 코드의 가독성이 떨어진다는 것이다. | 단점은 lambda를 사용하면 코드의 가독성이 떨어진다는 것이다. | ||
자 선택은 사용자의 몫이다. 자기가 사용하기 편하고, 가장 친숙한것을 사용하자. 그리고 작업에 가장 적당하다고 여겨 지는것을 사용하자. | |||
Python | == GUI 계산기 만들기 == | ||
[[Tkinter]]를 이용한 [[그래피컬 사용자 인터페이스]] ([[GUI]]) 계산기의 [[파이썬]] ([[Python]]) [[쏘쓰 코드]] ([[source code]])이다. | |||
<nowiki>''' cal.py</nowiki> | |||
<nowiki>''' | |||
A updated tiny calculator using the Tkinter GUI toolkit | A updated tiny calculator using the Tkinter GUI toolkit | ||
you can type in functions contained in module math | you can type in functions contained in module math | ||
for instance type in tan(pi/180) then click = | for instance type in tan(pi/180) then click = | ||
tested with | tested with Python 3.7.5 on Ubuntu 19.10 | ||
<nowiki>'''</nowiki> | <nowiki>'''</nowiki> | ||
from math import * | from math import * | ||
from functools import partial | from functools import partial | ||
Line 1,616: | Line 1,758: | ||
# the root will be self | # the root will be self | ||
tk.Tk.__init__(self) | tk.Tk.__init__(self) | ||
self.title(" | self.title("Darknet TK Calculator") | ||
# use width x height + x_offset + y_offset (no spaces!) | # use width x height + x_offset + y_offset (no spaces!) | ||
#self.geometry("300x150+150+50") | #self.geometry("300x150+150+50") | ||
Line 1,637: | Line 1,779: | ||
# partial takes care of function and argument | # partial takes care of function and argument | ||
cmd = partial(self.calculate, b) | cmd = partial(self.calculate, b) | ||
tk.Button(self, text=b, width=5, relief=rel, | tk.Button(self, text=b, width=5, relief=rel, command=cmd).grid(row=r, column=c) | ||
c += 1 | c += 1 | ||
if c > 4: | if c > 4: | ||
Line 1,687: | Line 1,828: | ||
app.mainloop() | app.mainloop() | ||
Updated Tiny Tkinter Calculator (Python) | [[사칙연산]]이 가능한 [[GUI]] [[계산기]]이다. 키보드로 직접 입력하면 tan(pi/180) 등 [[사칙 연산]] 외의 계산도 가능하다. | ||
[[우분투]] 19.10 기준으로, 파일 이름이 cal.py일 경우 [[파이썬]] 3.7.5에서는 [[터미널]]에서 | |||
sudo apt install python3-tk | |||
python3 cal.py | |||
[[명령어]]를 입력하면 실행된다. | |||
http://uoxqi4lrfqztugili7zzgygibs4xstehf5hohtkpyqcoyryweypzkwid.onion/?img=361615491111.png | |||
http://hostxvivwx3lzvfdnof2muv7q5fkcovkfa3nexlnl5zrelif2mawxkad.onion/image.php?di=631T | |||
http://pdogfxf7k6lyqe7uhmrokpc74nk2td75m4al5t6uvfhdvvxvng3nazid.onion\/tnibabrS30.jpg | |||
http://3b6clio4syptsnvvtzyxifqvtizyazgyowpp3v5f7dj3mzmfhyoy4iyd.onion/images/8f98719adf96e79c9647c790631c1c2e.png | |||
=== 쏘쓰 코드 설명 === | |||
아래 링크는 [[쏘쓰 코드]] ([[source code]]) 출처이다. | |||
* Updated Tiny Tkinter Calculator (Python) | |||
Nov 13th, 2013 9:14 pm | |||
https://www.daniweb.com/programming/software-development/code/467452/updated-tiny-tkinter-calculator-python | https://www.daniweb.com/programming/software-development/code/467452/updated-tiny-tkinter-calculator-python | ||
[[쏘스 코드]]에서 ' 나 " 3개로 싸인 부분은 [[주석]] ([[comment]])이다. 한 줄의 맨 앞에 #를 써놔도 주석이다. 자세한 설명은 [[파이썬]] 문서를 참조하라. | |||
# avoid integer division by Python2 | |||
from __future__ import division | |||
나 | |||
try: | |||
# Python2 | |||
import Tkinter as tk | |||
except ImportError: | |||
# Python3 | |||
import tkinter as tk | |||
등 [[파이썬]] 2를 위한 [[소스 코드]]는 삭제하거나 수정하였다. 왜냐하면 요즘에는 대부분의 사람들이 파이썬 3를 쓰기 때문이다. | |||
* Python Language - Integer Division | python Tutorial | |||
https://riptutorial.com/python/example/2797/integer-division | |||
* Difference between tkinter and Tkinter | |||
2013-07-24 | |||
https://stackoverflow.com/questions/17843596/difference-between-tkinter-and-tkinter | |||
from math import * | |||
from functools import partial | |||
import tkinter as tk | |||
functools에서 partial을 불러오라는 의미이다. *은 전부 불러오라는 의미이다. tkinter를 tk라는 이름으로 불러오라는 의미이다. | |||
MyApp [[클래스]] ([[class]]) 아래에 def로 [[정의]] ([[definition]])된 3개의 [[함수]] ([[function]])가 있다. 참고로 [[선언]] ([[declaration]])은 정의와는 약간 다르다. | |||
* C 언어 코딩 도장: 60.2 함수 선언과 정의 분리하기 | |||
https://dojang.io/mod/page/view.php?id=522 | |||
더 자새한 설명은 [[Tkinter]] 문서 참조. | |||
== 트킨터로 게임 만들기 == | |||
* [파이썬 게임 프로그래밍 공부] 1. tkinter 모듈 시작하기 | |||
2017-09-01 | |||
https://alegruz.imweb.me/blog/?idx=221667&bmode=view | |||
* [파이썬 게임 프로그래밍 공부] 2. 위젯에 간단한 오브젝트 생성하기 | |||
2017-09-01 | |||
https://alegruz.imweb.me/blog/?idx=221692&bmode=view | |||
== 함께 보기 == | |||
* [[필독 사항]] | |||
* [[다크넽]] ([[Darknet]]) | |||
* [[파이썬]] ([[Python]]) | |||
* [[파이게임]] ([[Pygame]]) | |||
* [[쏠쓰 코드]] ([[source code]], [[쏘쓰 코드]], [[쏘스 코드]], [[소스 코드]]) | |||
* [[오픈 쏠쓰]] ([[open source]], [[오픈 쏘쓰]], [[오픈 쏘스]], [[오픈 소스]]) | |||
[[Category:파이썬]] | [[Category:파이썬]] | ||
[[Category:프로그래밍]] | [[Category:프로그래밍]] |
edits