Python/Drawing2019. 1. 31. 16:15

tkinter 를 이용하여 선, 사각형, 다각형, 원, 텍스트, 이미지 그리기



tkinter 의 Canvas에 선과 사각형을 그리고 지우기


from tkinter import *

master = Tk()

canvas = Canvas(master, width=200, height=100)
canvas.pack()

canvas.create_line(0, 0, 200, 100)
canvas.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))

canvas.create_rectangle(50, 25, 150, 75, fill="#0000ff") #좌상단(50,20) 우하단(150,75)

i = canvas.create_line(100,0,100,100, fill="red")

canvas.coords(i, 0,100,100,100) # 기존 그림의 좌표 변경
canvas.itemconfig(i, fill="blue") # 기존 그림 색상 변경

canvas.delete(i) # 그려진 특정 그림 제거

#canvas.delete(ALL) # 캔바스의 모든 그림 제거
mainloop()



선, 사각형, 다각형, 호, 타원, 텍스트, 이미지 그리기

마우스 궤적을 따라 그리기

from tkinter import *

def on_move(evt) :
x1, y1 = (evt.x-1),(evt.y-1)
x2, y2 = (evt.x+1),(evt.y+1)
canvas.create_oval(x1,y1, x2,y2, fill="blue")

master = Tk()
master.title("Canvas에 도형 그리기")
master.geometry("600x400+300+100")
master.resizable(False, False)

canvas = Canvas(master, width=600, height=400, bg="orange")
canvas.pack()

# create_rectangle(x1,y1, x2,y2)
canvas.create_rectangle(50, 10, 150, 110, fill="#0000ff")
canvas.create_rectangle(70, 30, 170, 130, fill="#ff0000")

coord = (200, 10, 270, 200) # Tuple(바깥 원의 좌상단 모서리와 우하단 모서리)

# 반시계 방향으로 start각에서 출발하여 extend각으로 호를 그린다
arc = canvas.create_arc(coord, start=0, extent=180, fill="white")

# 바깥원의 좌상단 모서리, 우하단 모서리 좌표
oval = canvas.create_oval(300, 10, 400, 110, fill="#ffff00")

#최소한 3개의 꼭지점 좌표를 사용하여 다각형을 그린다(마지막 구간은 자동으로 연결됨)
poly = canvas.create_polygon(420,10, 460,10, 440,100, 480,100, fill="green")

# 시작점과 끝점을 연결하는 선을 그린다
line = canvas.create_line(10, 150, 500, 150, fill="black", width=3)

# 이미지 파일을 참고하여 이미지 그리기
filename = PhotoImage(file = "D:\\test\\bullet_left.png")
image = canvas.create_image(0, 200, anchor=NW, image=filename)

# 캔바스에 텍스트 그리기
text = canvas.create_text(100, 200, anchor=NW, font=("나눔고딕", 20), text="도형 그리기")

# 마우스 궤적을 따라 그리기
canvas.bind("<B1-Motion>", on_move)
mainloop()


Posted by cwisky
Python/GUI2019. 1. 30. 16:07

Python 윈도우에 사용할 수 있는 주요 위젯 테스트


원문참고

https://www.tutorialspoint.com/python/python_gui_programming.htm


Python 은 GUI 프로그램을 지원하기 위해 tkinter 모듈을 내장하고 있으므로 그리 어렵지 않게 윈도우 프로그램을 작성할 수 있다


기본 윈도우 띄우기

import tkinter
top = tkinter.Tk()
top.title("기본 윈도우")
# Code to add widgets will go here...
top.mainloop()


버튼을 누르면  메시지박스를 띄운다

import tkinter
import tkinter.messagebox as mb

top = tkinter.Tk()
top.title("버튼 이벤트 핸들러")

def click_handler(): # 버튼을 누르면 실행될 클릭 이벤트 핸들러
mb.showinfo( "MessageBox 제목", "MessageBox 내용")

B = tkinter.Button(top, text="Click", command=click_handler)

B.pack()
top.mainloop()


캔바스에 그리기

import tkinter

top = tkinter.Tk()
top.title("캔바스에 그리기")

C = tkinter.Canvas(top, bg="orange", height=250, width=300)

coord = 10, 50, 240, 210
arc = C.create_arc(coord, start=0, extent=150, fill="red")

C.pack()
top.mainloop()



메뉴바, 메뉴, 메뉴버튼

import tkinter as tk

top = tk.Tk() 


위와 같이 생성된 윈도우가 있을 때 ...

메뉴바와 메뉴는 동일하게 Menu 클래스를 사용하여 생성한다


menubar = Menu(top)  --> 최상위 윈도우에 직접 붙인 메뉴는 실제적으로 메뉴바 역할을 한다

filemenu = Menu(menubar)  --> 메뉴바에 직접 붙인 메뉴는 실제적으로 메뉴 역할을 한다


그리고 아래처럼 메뉴에 추가하는 것은 각 메뉴의 하위메뉴, 즉 메뉴 아이템이 된다

filemenu.add_command()

filemenu.add_radiobutton()

filemenu.add_checkbutton() 


Menubutton 은 메뉴바에 붙이는 위젯이 아니라 윈도우 클라이언트 영역에 일반 위젯과 같은 방법으로 붙일 때 사용한다

mbtn = Menubutton(top, text="Language")

mbtn.place(x=100,y=100) # pack(), grid(row=0,column=0)



Menubutton (메뉴를 선택하면 이벤트 핸들러가 호출됨)

from tkinter import *


def on_menu():
print("메뉴 눌림")

root = Tk()
root.title("메뉴버튼 만들기")
root.geometry("300x200")

mbutton = Menubutton(root, text='Language')
mbutton.grid(row=0, column=0)
picks = Menu(mbutton)
picks.add_command(label='Java', command=on_menu)
picks.add_command(label='C++', command=root.quit)
picks.add_command(label='Python', command=root.quit)
mbutton.config(menu=picks, bg='cyan', bd=1, relief=RAISED)

mbutton2 = Menubutton(root, text='Fruits')
mbutton2.grid(row=0, column=1)
picks2 = Menu(mbutton2)
picks2.add_command(label='Apple', command=root.quit)
picks2.add_command(label='Orange', command=root.quit)
picks2.add_command(label='Mellon', command=root.quit)
mbutton2.config(menu=picks2, bg='orange', bd=1, relief=RAISED)

root.mainloop()



Menubutton의 아이템으로 Radiobutton을 설정하는 예

from tkinter import *


def on_menu():
i = radioVar.get()
if i==1 : print("New")
elif i==2 : print("Open")

root = Tk()
root.title("메뉴버튼 (Radiobutton)만들기")
root.geometry("300x200")

filemenu = Menubutton(root, text='File')
#filemenu.grid(row=0, column=0)
filemenu.place(x=100,y=50)

radioVar = IntVar()
radioVar.set(1)
menuitems = Menu(filemenu)

menuitems.add_radiobutton(label='New', variable=radioVar, value=1, command=on_menu)
menuitems.add_radiobutton(label='Open', variable=radioVar, value=2, command=on_menu)
menuitems.add_radiobutton(label='Exit', variable=radioVar, value=3, command=root.quit)
filemenu.config(menu=menuitems, bg='orange', bd=1, relief=RAISED)

root.mainloop()



Menubutton의 아이템으로 Checkbutton을 설정하는 예

from tkinter import *


def on_menu():
if gravityVar.get() : print("Gravity ON")
if dragVar.get() : print("Drag ON")
if frictionVar.get() : print("Friction ON")

root = Tk()
root.title("메뉴버튼 (Checkbutton)만들기")
root.geometry("300x200")

forcemenu = Menubutton(root, text='Forces')
#forcemenu.grid(row=0, column=0)
forcemenu.pack()

gravityVar = BooleanVar()
gravityVar.set(True)
dragVar = BooleanVar()
frictionVar = BooleanVar()

menuitems = Menu(forcemenu)

menuitems.add_checkbutton(label='Gravity', variable=gravityVar, \
onvalue=True, offvalue=False, command=on_menu)
menuitems.add_checkbutton(label='Drag', variable=dragVar, \
onvalue=True, offvalue=False, command=on_menu)
menuitems.add_checkbutton(label='Friction', variable=frictionVar, \
onvalue=True, offvalue=False, command=on_menu)
forcemenu.config(menu=menuitems, bg='orange', bd=1, relief=RAISED)

root.mainloop()



Menubar, Menu 기본 설정 예

import tkinter as tk

def menu_handler(): # 체크버튼 메뉴를 클릭할 때마다 실행되는 핸들러
if lineVar.get() : print("Line Settings 선택")
if colorVar.get() : print("Color Settings 선택")
if surfaceVar.get() : print("Surface Settings 선택")

top = tk.Tk()
top.title("메뉴 기본설정")
top.geometry("300x200")

menubar = tk.Menu(top) # 윈도우 아래에 바로 붙이는 것은 메뉴바

lineVar = tk.BooleanVar()
lineVar.set(True)
colorVar = tk.BooleanVar()
surfaceVar = tk.BooleanVar()

settings_menu = tk.Menu(menubar) # 메뉴바에 붙이는 것은 메뉴 아이템
settings_menu.add_command(label="Line", command=menu_handler)
settings_menu.add_command(label="Color", command=menu_handler)
settings_menu.add_command(label="Surface", command=menu_handler)
menubar.add_cascade(label='Settings', menu=settings_menu)

help_menu = tk.Menu(menubar)
help_menu.add_command(label="Version", command=top.quit)
menubar.add_cascade(label="Help", menu=help_menu)

top.config(menu=menubar)
top.mainloop()



Menubar, Menu (checkbutton) 메뉴를 선택하면 메뉴아이템에 체크표시가 되며 핸들러가 실행

import tkinter as tk

def menu_handler(): # 체크버튼 메뉴를 클릭할 때마다 실행되는 핸들러
if lineVar.get() : print("Line Settings 선택")
if colorVar.get() : print("Color Settings 선택")
if surfaceVar.get() : print("Surface Settings 선택")

top = tk.Tk()
top.title("메뉴버튼 체크버튼")
top.geometry("300x200")

menubar = tk.Menu(top) # 윈도우 아래에 바로 붙이는 것은 메뉴바

lineVar = tk.BooleanVar()
lineVar.set(True)
colorVar = tk.BooleanVar()
surfaceVar = tk.BooleanVar()

settings_menu = tk.Menu(menubar) # 메뉴바에 붙이는 것은 메뉴 아이템
settings_menu.add_checkbutton(label="Line", onvalue=1, offvalue=False, variable=lineVar, \
command=menu_handler)
settings_menu.add_checkbutton(label="Color", onvalue=True, offvalue=0, variable=colorVar, \
command=menu_handler)
settings_menu.add_checkbutton(label="Surface", onvalue=1, offvalue=0, variable=surfaceVar, \
command=menu_handler)
menubar.add_cascade(label='Settings', menu=settings_menu)

top.config(menu=menubar)
top.mainloop()



Menubar, Menu, Radiobutton(메뉴 아이템에 Radiobutton 이 표시됨)

import tkinter as tk

def menu_handler(): # 체크버튼 메뉴를 클릭할 때마다 실행되는 핸들러
i = radioVar.get()
if i==1 : print("Line Settings 선택")
if i==2 : print("Color Settings 선택")
if i==3 : print("Surface Settings 선택")

top = tk.Tk()
top.title("메뉴바와 메뉴 Radiobutton")
top.geometry("300x200")

menubar = tk.Menu(top) # 윈도우 아래에 바로 붙이는 것은 메뉴바

radioVar = tk.IntVar()
radioVar.set(1)

settings_menu = tk.Menu(menubar) # 메뉴바에 붙이는 것은 메뉴 아이템
settings_menu.add_radiobutton(label="Line", variable=radioVar, value=1, \
command=menu_handler)
settings_menu.add_radiobutton(label="Color", variable=radioVar, value=2, \
command=menu_handler)
settings_menu.add_radiobutton(label="Surface", variable=radioVar, value=3, \
command=menu_handler)
menubar.add_cascade(label='Settings', menu=settings_menu)

top.config(menu=menubar)
top.mainloop()



주요 위젯들 ( Label, Entry, Radiobutton, Checkbutton, Text, Scale, Spinbox )

Label : 다른 위젯과 함께 쓰여서 문자열을 표시함

Entry : 한 행의  문자열을 입력할 수 있는 위젯

Radiobutton : 단일 선택 수단을 제공함(동일변수를 사용해야 함)

Checkbutton : 다중선택 가능

Text : 다중행의 문자열을 표시

Scale : 수직, 수평 슬라이더. from_, to, resolution 속성으로 값을 설정할 수 있다

Spin : 상하 삼각형을 클릭하여 숫자를 올리고 내릴 수 있다


from tkinter import *

def sel(): # Radiobutton 핸들러
text.delete(1.0, END)
text.insert(INSERT, "선택: " + str(ivar.get() ) )

def on_button(): # 버튼 핸들러
text.delete(1.0, END)
text.insert(INSERT, entry.get() )

def on_button2(): # 버튼 핸들러
idx = Lb1.curselection()
txt = Lb1.get(idx)
text.delete(1.0, END)
text.insert(INSERT, txt)

def on_check() : # Checkbutton 핸들러
text.delete(1.0, END)
text.insert(INSERT, f"CB1:{checkVar1.get()}, CB2:{checkVar2.get()}")

def on_change(v) : # Scale 위젯 이벤트 핸들러
#print("Scale:"+str(v))
#print("Scale:"+str(scale.get()))
text.delete(1.0, END)
text.insert(INSERT, str(scale.get()))

def on_spin():
text.delete(1.0, END)
text.insert(INSERT, str(spin.get()) )

root = Tk()
root.title("주요 Widget 테스트")
root.geometry("400x300")

label = Label( root, text="숫자입력" )
label.place(x=10, y=10)

entry = Entry(root, bd=1, width=5)
entry.place(x=70, y=10 )

bt = Button(root, text="확인", width=10, command=on_button )
bt.place(x=120, y=10)

ivar = IntVar()
radio1 = Radiobutton(root, text="Option 1", variable=ivar, value=1, command=sel)
radio2 = Radiobutton(root, text="Option 2", variable=ivar, value=2, command=sel)
radio1.place(x=10, y=50)
radio2.place(x=100, y=50)

Lb1 = Listbox(root, width=20, height=3)
Lb1.insert(1, "Python")
Lb1.insert(2, "Java")
Lb1.insert(3, "C++")
Lb1.place(x=10, y=100)

text = Text(root, width=30, height=1)
text.place(x=170, y=100)

bt2 = Button(root, text="리스트박스 선택확인", width=20, command=on_button2 )
bt2.place(x=170, y=130)

checkVar1 = IntVar()
checkVar2 = IntVar()
check1 = Checkbutton(root, text = "Movie", variable = checkVar1, \
onvalue = 1, offvalue = 0, height=1, width = 10, command=on_check)
check2 = Checkbutton(root, text = "Game", variable = checkVar2, \
onvalue = 1, offvalue = 0, height=1, width = 10, command=on_check)
check1.place(x=1, y=200)
check2.place(x=80, y=200)

scaleVar = DoubleVar()
scale = Scale( root, variable=scaleVar, orient=HORIZONTAL, command=on_change )
#scale = Scale( root, variable=scaleVar, from_=0.0, to=1.0, resolution=0.01,\
# orient=HORIZONTAL, command=on_change )
scale.place(x=170, y=160)

spin = Spinbox(root, from_=0, to=10, command=on_spin)
spin.place(x=170, y=220)

root.mainloop()


Posted by cwisky
Python/Network2019. 1. 30. 15:32

Python TCP Server, Client example


각 파일의 하단에 있는 다음의 코드는 파이썬 인터프리터가 직접 실행하는 경우에만 __name__ 변수의 값이 '__main__'이 되므로 다른 모듈에 의해서 이 파일이 사용될 때는 바로 실행되지 않고 함수 호출시에만 실행되도록 하기 위한 것이다


즉, python TCP_Server.py<enter> 으로 실행하는 경우에만 __name__ 변수의 값이 '__main__' 이다


TCP_Server.py

import socket
def Main():
host = "127.0.0.1"
port = 5000

s = socket.socket()
s.bind((host,port))

s.listen(1)
print("서버 대기 중...")
c, addr = s.accept()
print ("Connection from: " + str(addr))
while True:
data = c.recv(1024)
if not data:
break
print ("from connected user: " + str(data.decode()))
data = str(data.decode()).upper()
print ("sending: " + str(data) )
c.send(data.encode())

c.close()

if __name__ == '__main__' :
Main()



TCP_Client.py

import socket
def Main():
host = "127.0.0.1"
port = 5000

s = socket.socket()
s.connect((host, port))

message = input("->")
while message != 'q':
#print(message)
s.send(message.encode())
data = s.recv(1024) # buffer
print ('Received from server: ' + str(data.decode()))
message = input("->")

s.close()
if __name__ == '__main__' :
Main()


Posted by cwisky