반응형

Tkinter에서 다른 위젯의 배치를 위한 Frame을 사용할 수 있습니다. 아래는 Frame 예제입니다.

import tkinter as tk

root = tk.Tk()
root.title("GUI Frame")
root.geometry("640x480+100+100")
root.resizable(True,True)

frame1 = tk.Frame(root, relief="solid", bd=1, highlightcolor="red")
frame1.pack(side="top", fill="both", expand=True)

frame2 = tk.Frame(root, relief="solid", bd=2, bg="blue")
frame2.pack(side="bottom", fill="both", expand=True)

root.mainloop()

 

 

Frame Parameter

Param 의미 기본값 속성
width 프레임의 너비 0 상수
height 프레임의 높이 0 상수
relief 테두리 모양 flat flat, groove, raised, ridge, solid, sunken
bg 배경색 SystemButtonFace color
bd 테두리 두께 0 상수
padx 내부 x방향 패딩 1 상수
pady 내부 y방향 패딩 1 상수
highlightcolor 프레임이 선택될 때 색상 SystemWindowFrame color

 

반응형
반응형

Tkinter에서 위젯을 화면에 배치하는 방법에는 pack / grid / place의 세가지 방식이 있습니다. grid는 엑셀과 같은 이미지를 떠올리면 될 것 같습니다. 행과 열을 기준으로 위치시키는 방식이고, pack은 상/하/좌/우(동/서/남/북)으로 위치시키는 방식, 그리고 place는 절대좌표계를 이용해서 위치시키는 방식입니다.

 

1. Grid방식

import tkinter as tk

root = tk.Tk()
root.title("GUI Grid위젯배치")
root.geometry("640x480+100+100")
root.resizable(True,True)

bb1 = tk.Button(root, text="(0,0)")
bb1.grid(row=0,column=0)
bb2 = tk.Button(root, text="(0,1)")
bb2.grid(row=0,column=1)
bb3 = tk.Button(root, text="(0,2)")
bb3.grid(row=0,column=2)
bb4 = tk.Button(root, text="(1,0)")
bb4.grid(row=1, columnspan=3, sticky="ew")

root.mainloop()

 

Grid 속성

- 먼저 선언한 Grid부터 배치된다.

- 셀 단위로 배치되며, 한번에 여러 셀을 건너뛰어 배치할 수 없다.

- pack()과 같이 사용할 수 없으며, place()와는 같이 사용할 수 있다.

 

Grid Parameter

Param 의미 기본값 속성
row 행 위치 0  
column 열 위치 0  
rowspan 행 합치기 1  
columnspan 열 합치기 1  
sticky 할당된 공간 내에서 위치 조정. 어디에 고정할 것인가? - n(north), e(east), s(south), w(west)
news와 같이 전방향 고정으로 조합하여 사용 가능
ipadx x방향 내부 패딩 0  
ipady y방향 내부 패딩 0  
padx x방향 외부 패딩 0  
pady y방향 외부 패딩 0  

 

2. Pack방식

Pack은 상하좌우(동서남북) 에 위젯들을 위치시키는 방식입니다.

import tkinter as tk

root = tk.Tk()
root.title("GUI pack 위젯배치")
root.geometry("640x480+100+100")
root.resizable(True,True)

bb1 = tk.Button(root, text="left", width=10)
bb1.pack(side="left", fill="y")
bb2 = tk.Button(root, text="top", width=10)
bb2.pack(side="top")
bb3 = tk.Button(root, text="(right)", width=10)
bb3.pack(side="right")
bb4 = tk.Button(root, text="(bottom)", width=10)
bb4.pack(side="bottom", anchor="n")

root.mainloop()

 

Pack 속성

- 먼저 선언한 pack부터 배치된다.

- pack의 파라미터로 위젯의 크기를 변경할 수 있다.

- grid()와 같이 사용할 수 없으며 place()와는 같이 사용할 수 있다.

 

Pack Parameter

Param 의미 기본값 속성
side 위치(공간)할당 top top, bottom, left, right
anchor 고정 기준 center center, n(north), e(east), s(south), w(west)
news와 같이 전방향 고정으로 조합하여 사용 가능
fill 할당된 공간에 대한 크기 맞춤 none none, x, y, both
expand 미사용 공간 확보 False Boolean
ipadx x방향 내부 패딩 0  
ipady y방향 내부 패딩 0  
padx x방향 외부 패딩 0  
pady y방향 외부 패딩 0  

 

3. place방식

import tkinter as tk

root = tk.Tk()
root.title("GUI Grid위젯배치")
root.geometry("640x480+100+100")
root.resizable(True,True)

bb1 = tk.Button(root, text="(30,30)")
bb1.place(x=30, y=30)
bb2 = tk.Button(root, text="(100,30)")
bb2.place(x=100, y=30)
bb3 = tk.Button(root, text="(30,80)")
bb3.place(x=30, y=80)
bb4 = tk.Button(root, text="(100,80)")
bb4.place(x=100, y=80)

root.mainloop()

 

Place 속성

- 먼저 선언한 요소부터 배치된다.

- place의 절대 위치로 배치되며, 크기를 조정할 수 있다.

- pack(), grid()와 같이 사용할 수 있다.

 

place Parameter

Param 의미 기본값 속성
x x 좌표 0 상수
y y 좌표 0 상수
relx x좌표 배치 비율 0 0~1
rely y좌표 배치 비율 0 0~1
width 위젯 폭 0 상수
height 위젯 높이 0 상수
relwidth 위젯의 상대 너비 0 0~1
relheight 위젯의 상대 높이 0 0~1
anchor 고정 기준 nw n(north), e(east), s(south), w(west)
news와 같이 전방향 고정으로 조합하여 사용 가능

 

 

오늘은 헷갈리지 않도록 grid / pack / place의 속성에 대해 정리하는 시간을 가져봤습니다. 

반응형
반응형

예전에 테스트삼아 해봤는데, 오랫만에 하니까 잘 모르는 것도 있고, 좀 바뀐 부분도 있어서 정리도 할겸 올립니다. 아래와 같은 tkinter 화면을 만들겁니다.

 

1. main.py

우선 main.py에서는 구동만 시켜주고, 화면을 구성하는 파일은 gui.py로 별도 모듈로 만들 예정입니다.

import gui

if __name__ == '__main__':
    gui.main_screen()

 

2. gui.py

import tkinter as tk


def main_screen():
    root = tk.Tk()
    root.title("GUI Sample")
    root.geometry("640x480+100+100")
    root.resizable(True,True)
    root.configure(background='white')  # 배경을 흰색으로 하고,
    # root.wm_attributes("-transparentcolor", 'white') # 흰색을 투명으로 하면 투명한 앱이 됩니다.

    #레이블
    label_1=tk.Label(root, text="위젯 테스트", width=20,height=3,fg="red",relief="solid")
    label_1.pack()
    label_2=tk.Label(root, text="위젯 테스트2", width=20, height=3, fg="blue", relief="groove")
    label_2.pack()

    #리스트박스
    listbox = tk.Listbox(root, selectmode='extended', height=0)
    listbox.insert(0, "no1")
    listbox.insert(1, "no2")
    listbox.insert(2, "no3")
    listbox.insert(3, "no4")
    listbox.insert(4, "no5")
    listbox.pack()

    #체크박스
    checkVal1 = tk.IntVar()
    checkVal2 = tk.IntVar()
    checkBtn1 = tk.Checkbutton(root, text="체크박스 고르기1", variable=checkVal1, activebackground="blue")
    checkBtn2 = tk.Checkbutton(root, text="체크박스 고르기2", variable=checkVal2, activebackground="blue")
    checkBtn1.pack()
    checkBtn2.pack()

    #라디오버튼
    radioVal1=tk.IntVar()
    radioBtn1 = tk.Radiobutton(root, text="1번", value=3, variable=radioVal1)
    radioBtn2 = tk.Radiobutton(root, text="2번", value=6, variable=radioVal1)
    radioBtn3 = tk.Radiobutton(root, text="3번", value=9, variable=radioVal1)
    radioBtn1.pack()
    radioBtn2.pack()
    radioBtn3.pack()

    #상단메뉴
    def close():
        root.quit()
        root.destroy()

    menubar = tk.Menu(root)

    menu_1 = tk.Menu(menubar, tearoff=0)
    menu_1.add_command(label="Sub Menu1-1")
    menu_1.add_command(label="Sub Menu1-2")
    menu_1.add_separator()
    menu_1.add_command(label="종료", command=close)
    menubar.add_cascade(label="Menu1", menu=menu_1)

    menu_2 = tk.Menu(menubar, tearoff=0, selectcolor="red")
    menu_2.add_radiobutton(label="Sub Menu2-1", state="disable")
    menu_2.add_radiobutton(label="Sub Menu2-2")
    menu_2.add_radiobutton(label="Sub Menu2-3")
    menubar.add_cascade(label="Menu2", menu=menu_2)

    menu_3 = tk.Menu(menubar, tearoff=0)
    menu_3.add_checkbutton(label="Sub Menu3-1")
    menu_3.add_checkbutton(label="Sub Menu3-2")
    menu_3.add_checkbutton(label="Sub Menu3-3")
    menubar.add_cascade(label="Menu3", menu=menu_3)

    root.config(menu=menubar)

    # 메뉴 버튼 (상단 메뉴바랑 상관 없음)
    menubutton = tk.Menubutton(root, text="Menu Button", relief="raised", direction="right")
    menubutton.pack()

    menu = tk.Menu(menubutton, tearoff=0)
    menu.add_command(label="Sub-1")
    menu.add_separator()
    menu.add_command(label="Sub-2")
    menu.add_command(label="Sub-3")

    menubutton["menu"] = menu

    # 배치연습
    bb1=tk.Button(root, text="(50,50)")
    bb1.place(x=50,y=50)
    bb2 = tk.Button(root, text="(130,50)",width=10, height=1)
    bb2.place(x=130, y=50)
    bb3 = tk.Button(root, text="(50,100)", border=3)
    bb3.place(x=50, y=100)
    bb4 = tk.Button(root, text="(130,100)")
    bb4.place(x=130, y=100)


    root.mainloop()
반응형
반응형

이전 포스팅의 투명한 배경에 이어, 둥근 버튼 구현하기를 알아보겠습니다.

요즘 tkinter와 kivy를 번갈아가며 사용해보고 있는데, 서로 장단점이 존재하네요. 어느것도 완벽한게 없는듯 합니다.

tkinter는 둥근버튼이 없어서 별도로 구현해야 하는 반면 투명한 배경처리가 가능하고,

kivy는 투명한 배경은 안되도 둥근버튼은 쉽게 구현이 되네요. 

import tkinter as tk

root = tk.Tk()
# root.attributes('-alpha', 0.3)  # 앱 전체가 투명해짐
root.wm_attributes("-transparentcolor", "white")

canvas = tk.Canvas(root, width=600, height=300, bg='white')
canvas.grid(columnspan=3, rowspan=3)
hello = tk.Label(root, text="Hello World", font="Raleway", bg='white')
hello.grid(columnspan=3, column=0, row=0)

# 이미지의 사이즈 변경. x방향 1/2, y방향 1/2
btn_img = tk.PhotoImage(file="button.png").subsample(2, 2)
# compound='center'로 이미지의 위치 설정하고 반대편에 텍스트 배치
# (left,right,top,bottom등 가능)
button = tk.Button(root, text="click", image=btn_img, compound='center', borderwidth=0, bg='white')
button.grid(column=1, row=1)

root.mainloop()

 

반응형
반응형

 

 

회사에서는 예전에 만들어둔 Visual Basic 6.0을 어쩌지 못해 계속 사용하고 있습니다. 저는 그 유지보수 담당입니다. 다른 언어로 갈아 엎고는 싶지만,,,  온지 얼마 안돼서..아니, 실력이 아직 한참 모자라서 그냥 유지보수 중입니다.

그러나 마음만은 항상 다른 언어로 포팅하려고 준비하고 있습니다. 배포가 편리한 Java를 유력 후보로 생각하고 있는데요..(C# 안사줌..ㅠㅠ)

그 전에 간단한 프로그램 프로토타입 설계를 위해 tkinter를 손대보기로 했습니다.

 

결론은, 필요한 기능 그때그때 불러다 쓸 기본 위젯 종합 선물세트를 만들었습니다.  필요할 때 골라 쓰려구요. 실행하면 이런 gui프로그램이 나오게 될 것입니다.

 

그리고, 소스는 https://076923.github.io/ 사이트를 참조했음을 알려드리며, 개발자분께 감사드립니다. 자세한 모듈 속성에 대한 설명도 해당 사이트에서 확인할 수 있습니다.


import tkinter

window=tkinter.Tk()

#기본 설정
window.title("GUI Sample")
window.geometry("640x640+100+100")  #너비X높이+X좌표+Y좌표
window.resizable(True, True)        #사이즈 변경 가능

#레이블
label_1=tkinter.Label(window, text="위젯 테스트용입니다.", width=20, height=5, fg="red", relief="solid")
label_2=tkinter.Label(window, text="", width=20, height=3, fg="red", relief="solid")

label_1.pack()
label_2.pack()

#버튼
button = tkinter.Button(window, text="hi", overrelief="solid", width=20)
button.pack()


# 엔트리 함수
def calc(event):
    label.config(text="결과=" + str(eval(entry.get())))

#엔트리 입력창
entry=tkinter.Entry(window)
entry.bind("<Return>", calc)
entry.pack()

#리스트박스
listbox=tkinter.Listbox(window, selectmode='extended', height=0)
listbox.insert(0, "no1")
listbox.insert(1, "no2")
listbox.insert(2, "no3")
listbox.insert(3, "no4")
listbox.insert(4, "no5")
listbox.pack()

#체크박스 함수
def flash():
    button.flash()

#체크박스
CheckVariety_1=tkinter.IntVar()
CheckVariety_2=tkinter.IntVar()

checkbutton1=tkinter.Checkbutton(window,text="O", variable=CheckVariety_1, activebackground="blue")
checkbutton2=tkinter.Checkbutton(window, text="Y", variable=CheckVariety_2)
checkbutton3=tkinter.Checkbutton(window, text="X", variable=CheckVariety_2, command=flash)

checkbutton1.pack()
checkbutton2.pack()
checkbutton3.pack()

#라디오버튼
RadioVariety_1=tkinter.IntVar()

#value값이 같을 경우 함께 선택됨
radio1=tkinter.Radiobutton(window, text="1번", value=3, variable=RadioVariety_1)
radio1.pack()
radio2=tkinter.Radiobutton(window, text="2번", value=3, variable=RadioVariety_1)
radio2.pack()
radio3=tkinter.Radiobutton(window, text="3번", value=9, variable=RadioVariety_1)
radio3.pack()

#메뉴
def close():
    window.quit()
    window.destroy()

menubar=tkinter.Menu(window)

menu_1=tkinter.Menu(menubar, tearoff=0)
menu_1.add_command(label="Sub Menu1-1")
menu_1.add_command(label="Sub Menu1-2")
menu_1.add_separator()
menu_1.add_command(label="종료", command=close)
menubar.add_cascade(label="Menu1", menu=menu_1)

menu_2=tkinter.Menu(menubar, tearoff=0, selectcolor="red")
menu_2.add_radiobutton(label="Sub Menu2-1", state="disable")
menu_2.add_radiobutton(label="Sub Menu2-2")
menu_2.add_radiobutton(label="Sub Menu2-3")
menubar.add_cascade(label="Menu2", menu=menu_2)

menu_3=tkinter.Menu(menubar, tearoff=0)
menu_3.add_checkbutton(label="Sub Menu3-1")
menu_3.add_checkbutton(label="Sub Menu3-2")
menu_3.add_checkbutton(label="Sub Menu3-3")
menubar.add_cascade(label="Menu3", menu=menu_3)


#메뉴 버튼
menubutton=tkinter.Menubutton(window,text="Menu Button", relief="raised", direction="right")
menubutton.pack()

menu=tkinter.Menu(menubutton, tearoff=0)
menu.add_command(label="Sub-1")
menu.add_separator()
menu.add_command(label="Sub-2")
menu.add_command(label="Sub-3")

menubutton["menu"]=menu
window.config(menu=menubar)

#배치(place(), pack(), grid())
b1=tkinter.Button(window, text="top")
b1.pack(side="top")
b2=tkinter.Button(window, text="bottom")
b2.pack(side="bottom")
b3=tkinter.Button(window, text="left")
b3.pack(side="left")
b4=tkinter.Button(window, text="right")
b4.pack(side="right")

bb1=tkinter.Button(window, text="(50, 50)")
bb2=tkinter.Button(window, text="(50, 100)")
bb3=tkinter.Button(window, text="(100, 150)")
bb4=tkinter.Button(window, text="(0, 200)")
bb5=tkinter.Button(window, text="(0, 300)")
bb6=tkinter.Button(window, text="(0, 300)")

bb1.place(x=50, y=50)
bb2.place(x=50, y=100, width=50, height=50)
bb3.place(x=100, y=150, bordermode="inside")
bb4.place(x=0, y=200, relwidth=0.5)
bb5.place(x=0, y=300, relx=0.5)
bb6.place(x=0, y=300, relx=0.5, anchor="s")

"""     grid() 는 pack()과 함께 쓰일 수 없음

bbb1=tkinter.Button(window, text="(0,0)")
bbb1.grid(row=0, column=0)
bbb2=tkinter.Button(window, text="(1,1)", width=20)
bbb2.grid(row=1, column=1, columnspan=3)
bbb3=tkinter.Button(window, text="(1,2)")
bbb3.grid(row=1, column=2)
bbb4=tkinter.Button(window, text="(2,3)")
bbb4.grid(row=2, column=3)
"""

window.mainloop()

 

필요하신 분, 가져다가 적극 활용하시기 바랍니다.

감사합니다.^^

 

 

 

 

 

 

 

 

 

 

반응형

+ Recent posts