'분류 전체보기'에 해당되는 글 99건

  1. 2019.03.03 Removing C++ Class
  2. 2019.03.01 UE4 Install 1
  3. 2019.02.01 Sprite Animations in Python with Pilow Module
  4. 2019.01.31 Python Math Module
  5. 2019.01.31 Ball Animation
  6. 2019.01.31 Canvas Drawing
  7. 2019.01.30 GUI example
  8. 2019.01.30 TCP Server, Client
  9. 2019.01.29 Underscores in Python
  10. 2019.01.23 Date Time

언리얼 엔진 프로젝트에서 C++ 클래스 삭제하기


1. Visual Studio를 닫는다

2. UE4 Editor를 닫는다


탐색기에서 프로젝트 폴더를 찾아서


3. 프로젝트이름/Source/프로젝트이름/Public, Private 폴더 안에서 *.h, *.cpp 파일 삭제

4. 프로젝트 이름/Binaries/ 폴더 삭제


프로젝트 이름/프로젝트이름.uproject 파일을 찾아서


5. uproject 파일에서 마우스 우측 > Generate Visual Studio Project Files 선택

6. UE4 Editor 를 사용하여 정상적으로 프로젝트를 다룬다



Posted by cwisky
UE Install2019. 3. 1. 13:00

언리얼 엔진을 설치할 때 설치 디렉토리를 D 드라이브로 설정하더라도 대부분의 내용(약 20GB)이 C 드라이브에 설치되고 D 드라이브에는 약 350MB에 해당하는 DirectXRedist, Launcher 폴더만 설치되는 것을 확인할 수 있다.  


언리얼 엔진을 설치한 후에 기본 드라이브의 용량 부족문제 등으로 인하여 다른 드라이브로 이동하려는 경우가 있는데 다음과 같은 방법을 사용하면 운영체제가 설치된 드라이브를 피해서 언리얼 엔진을 다른 드라이브에 옮겨서 사용할 수 있다


결론적으로 모든 파일을 C가 아닌 다른 드라이브로 잘라내서 이동하고 원래의 위치에는 이동한 목적지 위치의 링크를 생성해두면 된다



언리얼 엔진 설치

디폴트 설정으로 설치를 완료한다



C 드라이브에 설치된 폴더를 다른 드라이브로 이동

윈도우라면 

C:\Program Files\Epic Games 안에 다음과 같은 3개의 폴더가 생성되어 있다

UE4_21, DirectXRedist, Launcher

이 폴더를 모두 잘라내서 D:\Epic Games(임의의 폴더명) 안에 복사한다



원래의 위치에 각 폴더의 링크 생성

윈도우에서 CMD를 실행( 관리자 권한으로 실행 )하고 다음과 같은 명령을 사용한다

프롬프트 상의 임의의 위치에서 아래의 명령을 사용하면 C:\Program Files\Epic Games\ 안에 링크를 생성할 수 있다. cd 명령을 사용하여 C:\Program Files\Epic Games\ 안으로 이동할 필요는 없다


mklink /J "C:\Program Files\Epic Games\UE_4.21" "D:\Epic Games\UE_4.21"

mklink /J "C:\Program Files\Epic Games\DirectXRedist" "D:\Epic Games\DirectXRedist"

mklink /J "C:\Program Files\Epic Games\Launcher" "D:\Epic Games\Launcher"



작동 테스트

바탕화면의 UE 아이콘을 더블클릭하여 Launcher와 언리얼 엔진이 정상적으로 실행되면 성공이다



CMD에서 실제 명령을 실행한 예

Microsoft Windows [Version 10.0.17134.590]

(c) 2018 Microsoft Corporation. All rights reserved.


C:\windows\system32>mklink /J "C:\Program Files\Epic Games\UE_4.21" "D:\Epic Games\UE_4.21"

Junction created for C:\Program Files\Epic Games\UE_4.21 <<===>> D:\Epic Games\UE_4.21


C:\windows\system32>


Posted by cwisky
Python/Sprite Anim2019. 2. 1. 15:04

Python에서 Pillow 모듈을 사용한 스프라이트 애니메이션 예제


Pillow 모듈 설치

PIL(Python Image Library) 프로젝트가 중단되고 그 후속 프로젝트가 Pillow 이며 Python 3 이 타겟이다


Pillow 매뉴얼

pillow.pdf


원문강좌 참조: http://zetcode.com/python/pillow/


Pillow 모듈 설치

Python이 설치되어 있고 PATH 환경변수에 Python의 경로가 설정되어 있다면 윈도우의 CMD 콘솔에서 다음과 같은 명령을 통해 Pillow 모듈을 간단하게 설치할 수 있다


pip install pillow



PIL 이미지를 tk 이미지로 변환하여 tk Canvas에 그리는 예

from tkinter import *
from PIL import Image, ImageTk

master = Tk()
master.title("Canvas에 PIL 이미지 그리기")
master.geometry("600x400+300+100")
master.resizable(False, False)

canvas = Canvas(master, width=600, height=400, bg="orange")
canvas.pack()
pil_img = Image.open("D:/test/explosion17.png")

# 이미지를 다루는 외부 프로그램을 열고 이미지를 보여준다
#pil_img.show()

# PIL 이미지를 tkinter 이미지와 호환되도록 변환
tk_img = ImageTk.PhotoImage(pil_img)

# tkinter Canvas에 이미지를 그린다
image = canvas.create_image(0, 0, anchor=NW, image=tk_img)

master.mainloop()



소스 이미지에서 특정 영역의 이미지 데이터만 가져오기

스프라이트 시트에서 애니메이션의 한 프레임에 해당하는 이미지 영역을 선택적으로 읽어온다

from tkinter import *
from PIL import Image, ImageTk

master = Tk()
master.title("Canvas에 PIL 이미지 그리기")
master.geometry("600x400+300+100")
master.resizable(False, False)

canvas = Canvas(master, width=600, height=400, bg="orange")
canvas.pack()
pil_img = Image.open("D:/test/explosion17.png")

# 스프라이트 시트에서 한 프레임 이미지를 읽어온다
box = 0,0,64,64
pil_frame_img = pil_img.crop(box)

# PIL 이미지를 tkinter 이미지와 호환되도록 변환
frame_img = ImageTk.PhotoImage(pil_frame_img)

# tkinter Canvas에 이미지를 그린다
image = canvas.create_image(0, 0, anchor=NW, image=frame_img)

master.mainloop()



스프라이트 애니메이션을 구현한 예

사용된 스프라이트 시트는 이 페이지 하단에 첨부


from tkinter import *
from PIL import Image, ImageTk
import time

master = Tk()
master.title("스프라이트 애니메이션 예제")
master.geometry("600x400+300+100")
master.resizable(False, False)

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

# 애니메이션을 구성하는 모든 프레임 이미지가 저장된 스프라이트 시트를 로드한다
pil_img = Image.open("D:/test/explosion17.png")

# 스프라이트 시트에서 확인된 한 프레임 영역의 폭(w)과 높이(h)
w = 64
h = 64

# 스프라이트 시트로부터 순차적으로 프레임 이미지를 읽어와서 캔바스에 표시한다
for y in range(5) :
for x in range(5) :

# 스프라이트 시트에서 읽어올 한 프레임 영역의 좌표를 계산한다
box = x*w, y*w, (x+1)*h, (y+1)*h
# 스프라이트 시트에서 한 프레임 영역 이미지를 읽어온다
pil_frame_img = pil_img.crop(box)
# PIL 이미지를 tkinter 이미지로 변환한다
frame_img = ImageTk.PhotoImage(pil_frame_img)
# tkinter 이미지를 캔바스에 그린다
image = canvas.create_image(0, 0, anchor=NW, image=frame_img)
# 윈도우(화면)를 업데이트한다
master.update()
# 루프를 0.025초 쉰다(애니메이션 속도를 결정함)
time.sleep(.025)

master.mainloop()



Posted by cwisky
Python/Math2019. 1. 31. 22:14

파이썬 math 모듈에 포함된 함수


import math

# math 모듈이 필요 없는 수학 함수
print(" 2**3 : "+ str( 2**3 )) # 8
print(" abs(-25) : " + str ( abs(-25) ) ) # 25
print(" round(1.5) : " + str( round(1.5))) # 2
print(" round(1.1234567, 1) : " + str( round(1.1234567, 1))) # 1.1
print(" sum([1,2,3,4]) : "+ str( sum([1,2,3,4]))) # 10
print(" max([1,2,3,4]) : "+ str( max([1,2,3,4]))) # 4
print(" min([1,2,3,4]) : "+ str( min([1,2,3,4]))) # 1
print(" pow(2,3) : "+ str(pow(2,3)) ) # 8
print(" divmod(5,2) "+ str( divmod(5,2))) # (2,1)

# 여기서부터는 math 모듈이 필요함

print("pi:"+ str ( math.pi ) ) # 3.141592653589793
print("e:"+ str ( math.e ) ) # 2.718281828459045

print(" math.ceil(3.14) : "+ str( math.ceil(3.14))) # 4
print(" math.floor(3.14) : "+ str( math.floor(3.14))) # 3
print(" math.trunc(2.3) : "+ str( math.trunc(2.3))) # 2
print(" math.factorial(4) : "+ str( math.factorial(4))) # 24
print(" math.pow(2,3) "+ str( math.pow(2,3))) # 8
print(" math.sqrt(9) "+ str( math.sqrt(9))) # 3
print(" math.copysign(1.5, -1.3) : "+ str(math.copysign(1.5, -1.3))) # -1.5
print(" math.fabs(-2.7) : "+ str(math.fabs(-2.7))) # 2.7
print(" math.fmod(-13.2, 3) : "+ str(math.fmod(-13.2,3))) # -1.1999999999999993
print(" math.fsum([1,2,3]) : "+ str( math.fsum([1,2,3]))) # 6.0
print(" math.modf(2.718) : "+ str( math.modf(2.7))) # (0.7000000000000002, 2.0)
print(" math.exp(2) : "+ str( math.exp(2))) # 7.38905609893065

# 삼각함수
print(" math.degrees(math.pi) : "+ str( math.degrees(math.pi))) # 180.0
print(" math.radians(180) : "+ str( math.radians(180))) # pi

rad = math.pi/2 # 90 deg
sinv = math.sin(rad)
cosv = math.cos(rad)
tanv = math.tan(rad)

# 역삼각함수
math.asin(sinv)
math.acos(cosv)
math.atan(tanv)
math.atan2(sinv, cosv)

# 쌍곡선 함수
sinhv = math.sinh(rad)
coshv = math.cosh(rad)
tanhv = math.tanh(rad)

# 역쌍곡선 함수
math.asinh(sinhv)
math.acosh(coshv)
math.atanh(tanhv)

# 밑을 지정하는 일반로그
print(" math.log(8,2) "+ str( math.log(8,2))) # 3.0

# 밑이 자연상수(e)인 자연로그
val = math.pow( math.e, 3 )
print(" math.log("+str(val)+") "+ str( math.log(val))) # 3.0

# 밑이 10인 상용로그
print(" math.log10(100) "+ str( math.log10(100))) # 2.0

# 복소수
comp1 = 2 + 3j
comp2 = 3 + 4j
comp3 = comp1 + comp2
print(comp3) # 5 + 7j


Posted by cwisky
Python/Ball Anim2019. 1. 31. 18:47

tkinter 모듈을 이용하여 사각영역에서 공이 이동하면서 테두리에서 반사하는 기본적인 애니메이션 만들기


from tkinter import *
import time

win = Tk()
win.geometry("800x800")
win.title("이동 애니메이션 기본")

c = Canvas(win ,width=800 ,height=800)
c.pack()

oval = c.create_oval(5,5,60,60,fill='red')

a = 1
b = 1

for x in range(0 ,100):
c.move(oval,a,b)
win.update()
time.sleep(.03)

win.mainloop()



경계에 충돌하고 반사하는 공 애니메이션

from tkinter import *
import time

win = Tk()
win.title("First title")
win.geometry("600x400")

c = Canvas(win ,width=600 ,height=400, bg="#559955")
c.pack()

oval = c.create_oval(5,5,60,60,fill='white')

xd = 2
yd = 2

while True:
c.move(oval,xd,yd)
# 현재 볼의 위치([x1,y1, x2,y2])를 구함
p = c.coords(oval) # Return a list of coordinates for the item given in ARGS.

if p[3] >= 400 or p[1] <=0: # 상하 영역을 벗어났는지 확인
yd = -yd
if p[2] >=600 or p[0] <=0: # 좌우 영역을 벗어났는지 확인
xd = -xd

win.update()
time.sleep(0.01)

win.mainloop()


Posted by cwisky
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
Python/Underscores2019. 1. 29. 16:35

Python 에서 언더스코어는 5가지 사용법으로 구분된다


Single Underscore:

  • In Interpreter
  • After a name
  • Before a name

Double Underscore:

  • __leading_double_underscore
  • __before_after__


언더스코어가 독립적으로 사용되는 경우
파이썬 프롬프트(인터프리터) 상에서 가장 마지막에 실행된 표현식의 값을 가진 변수로 사용된다

D:\PythonProjects>python
Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 22:20:52) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 1+2
3
>>> _
3
>>> _ * 2
6
>>> _ += 4
>>> _
10
>>>



다음은 위와 같이, 파이썬 프롬프트에서 _ 기호가 변수로 사용되는 경우이다

추출된 값을 굳이 사용할 필요가 없는 경우에 그 값을 무시하는 의도


# 아래의 문장은 0 ~ 4까지 화면에 표시한다

for x in range(5):

    print(x)


# 아래의 문장도 위와 동일한 결과를 표시한다

for _ in range(5):

    print(_)


# 아래의 문장은 0 ~4까지의 숫자가 필요한 것이 아니라 5번 루프를 실행할 목적으로 사용된다

for _ in range(5):

    print("Hello")



def test():

  return (3,5,2,1)     # Tuple을 리턴하는 함수


print( test() )

a, b, _, _ = test()     # 리턴된 튜플의 두번째 값 까지만 필요한 경우

print(f"a:{a}, b:{b}")



이름 뒤에 _ 가 붙는 경우 (예약어는 변수명으로 사용할 수 없으므로 이름 뒤에 _를 붙인 경우)

class Product:

  def __init__(self):

    self.name = "Galaxy 10"

  


def printClsName(class_):    # class라는 변수명을 사용하고자 하지만 Python 예약어라서 안됨

    print(class_)


p1 = Product()

printClsName(p1.__class__)    # <class '__main__.Product'>



함수이름 왼쪽에 _가 붙는 경우

보안성이 약한 private 의미로 사용하는 경우, 함수이름 왼쪽에 _붙이면 다른 파일에서 from file_name import * 방법을 사용하여 가져올 때 해당 함수는 누락되어 사용할 수가 없게 된다

util.py

def func1():

    print("public function")


def _func2():

    print("private function")


위의 util.py 파일을 다른 파일에서 사용하는 경우 ( _func2() 함수는 정의되지 않은 함수라는 오류 발생 )

from util import *


func1()

_func2()


위의 오류는 다음과 같은 방법으로 해결된다

import util


util.func1()

util._func2()



더블 언더스코어를 변수 왼쪽에 붙인 경우(Mangling)

Product.py ( __price 변수는 선언된 클래스에서 그 이름으로 사용가능하지만 외부에서는 안됨)

class Product:

  def __init__(self):

    self.name = "Galaxy 10"

    self.__price = 300


  def print_info(self):

      print(f"name:{self.name}")

      print(f"price:{self.__price}")


위의 클래스를 외부에서 사용하면서 __price 변수에 직접 접근하는 경우에 오류가 발생한다. 더블언더스코어가 2개 붙은 변수는 인터프리터에서 변수 이름을 고칠 때 _클래스명__변수명 형식으로 변경하기 때문이다. 이런 작업을 Mangling(맹글링)이라고 한다

import Product as p


p1 = p.Product()

#print( p1.__price)                  # 오류


print( p1._Product__price)        # 정상

p1.print_info()                       # 정상



__이름__ 형식의 함수/변수

인터프리터에 내장된 특수한 함수/변수를 나타낸다

__init__() 생성자 함수가 여기에 속한다

또한 클래스 안에 정의할 수 있는 가감승제 메소드( __add__(), __sub__(), __mul__(), __divmod__() 등)도 있다. 이들 함수가 클래스에 정의되어 있으면  obj.__add__(2,3) 형식으로 호출할 수 도 있고 수학의 덧셈식( obj1 + obj2)형식으로도 호출할 수 있기 때문에 연산자 오버로드용으로 사용할 수 있다



__add__() 함수를 정의하여 벡터 덧셈을 직관적으로 표현한 경우(연산자 오버로드)

class vector:


  def __init__(self, x,y,z):

    self.x = x

    self.y = y

    self.z = z


  def __add__(self, other):

    x_ = self.x + other.x

    y_ = self.y + other.y

    z_ = self.z + other.z

    return vector(x_,y_,z_)


  def print_info(self):

    print(f"x:{self.x}, y:{self.y}, z:{self.z}")


v1 = vector(1,2,3)

v2 = vector(4,5,6)

v3 = v1 + v2

v3.print_info()     #  x:5, y:7, z:9



Weak Private, Strong Private

class UnderscoreTest:
def __init__(self, val1, val2):
self._val1 = val1 # Weak Private
self.__val2 = val2 # Strong Private
def print_dict(self) :
print(self.__dict__)

u = UnderscoreTest(100, 200)
u.print_dict() # {'_val1': 100, '_UnderscoreTest__val2': 200}
print(u._val1)
#print(u.__val2) # 오류:__val2 변수가 선언되지 않음
#print(u.val1) # 오류:val1 변수가 선언되지 않음
print( u._UnderscoreTest__val2 )


Setter, Getter에서는 싱글 언더스코어, 더블 언더스코어 모두 사용할 수 있고 심지어 3개 이상도 가능하다

변수 왼쪽에 언더스코어를 2개이상 사용하면 Mangling 이 적용된다

class UnderscoreTest:
def __init__(self, val1, val2):
self.val1 = val1 # Weak Private
self.val2 = val2 # Strong Private
@property
def val1(self):
print("val1 getter")
return self._val1

@val1.setter
def val1(self, v):
print("val1 setter")
self._val1 = v

@property
def val2(self):
print("val2 getter")
return self.__val2

@val2.setter
def val2(self, v):
print("val2 setter")
self.__val2 = v

def print_dict(self) :
print(self.__dict__)

u = UnderscoreTest(100, 200) # val1 setter, val2 setter 호출
u.print_dict() # {'_val1': 100, '_UnderscoreTest__val2': 200}
print(u.val1) # val1 getter 호출
#print(u.__val2) # 오류:__val2 변수가 선언되지 않음(Mangling)
print(u._val1) # _val1에 직접접근, val1 setter호출 안됨
print( u._UnderscoreTest__val2 ) # Mangling 효과, _UnderscoreTest__val2에 직접접근


Posted by cwisky
PHP/Time2019. 1. 23. 23:33

<?php

// 시간 문자열을 날짜 객체로 변환

$date = new DateTime('2019-01-23 12:30:23');


// 날짜 객체를 시간 문자열로 변환

echo $date->format('Y-m-d H:i:s');


// 현재 로컬시간 구하기

date_default_timezone_set("Asia/Seoul");

echo date('Y-m-d H:i:s'); //로컬시간을 문자열로 리턴


Posted by cwisky