원격 저장소 클론, 푸시 테스트하기

- 지난번에 원격저장소에 푸시했었는데, 지금 다른 컴퓨터에서 작업하려고 한다.

- 원격저장소로부터 클론받고 잘 푸시 되는지 확인해보자

- 안에 파일들이 정상적으로 내려받았다.

 

- 잘 푸시되는지 보기위해 텍스트파일 하나 만들고 아무거나 입력후 커밋해보자

 -> 커밋하는 사람인지 누구인지 식별문제로 커밋되지 않는다. 아래 명령어대로 이메일과 이름을적자

- 컨피그 명령을 입력하면 커밋이 된다.

- 이제 푸시하면 깃헙 저장소에 잘 올라간걸 볼수있다.

 

 

 

섭씨 화씨 온도 변환기 구현

 

from tkinter import Frame, Label, Entry, DoubleVar, W,\
                Tk, Button

class App:
    def __init__(self, master):
        frame = Frame(master)
        frame.pack()
        # deg C : 엔트리
        Label(frame, text = "deg C").grid(row=0, column=0)
        self.c_var = DoubleVar()
        self.c_var.set(0.0);
        Entry(frame, textvariable=self.c_var).grid(row=0, column=1)
        # def F : 엔트리
        Label(frame, text="deg F").grid(row=1, column=0)
        self.f_var = DoubleVar()
        self.f_var.set(32.0)
        Label(frame, textvariable=self.f_var).grid(row=1, column=1, sticky=W)
        # Convert 버
        button = Button(frame, text="Convert", command = self.convert)
        button.grid(row=2, columnspan=2)
    
    def convert(self):
        c = self.c_var.get()
        self.f_var.set(c * 1.8 + 32)

window = Tk()
window.wm_title("temp converter")
app = App(window)
window.mainloop()

 

 

계산기 구현

from tkinter import Frame, Label, Entry, DoubleVar, W,\
                Tk, Button, StringVar, SUNKEN, NSEW
import tkinter as tk



class Calculator(Frame):
    def __init__(self):
        Frame.__init__(self)
        self.option_add("*Font","arial 16 bold")
        self.grid(row = 0, column=0)
        self.master.resizable(0, 0)
        #이 화면을 맨 위에 표시되게 함.
        self.master.wm_attributes("-topmost", 1)
        self.make_form()
    
    
    # 버튼 입력때마다 호출, 전달받은 c를 strExpr에 추가. 엔트리에 반영되면서 커서도이동
    def update_expr(self, c):
        self.strExpr.set(self.strExpr.get() + c)
        self.entry.icursor(len(self.strExpr.get()))
 
    #selfExpr의 계산 내용을 계산 후 결과를 strExpr에 대입, 커서는 맨뒤로 이동
    def calc(self):
        try:
            self.strExpr.set(eval(self.strExpr.get()))
            self.entry.icursor(len(self.strExpr.get()))
        except:
            self.strExpr.set("Error")
    
    def make_form(self):
        self.strExpr = StringVar()
        self.entry = Entry(self, relief=SUNKEN, textvariable=self.strExpr)
        self.entry.grid(row=0, column=0, columnspan=5, sticky=NSEW)
        self.entry.bind("<Return>", lambda event, s=self: s.calc())
        self.entry.focus() # 이 엔트리에 문자, 연산자 입력 가능하도록 함
        
        """
        2번째 행부터 
        계산기 숫자버튼 구현
        7 8 9
        4 5 6
        1 2 3        
        """
        for r, item in enumerate(("789", "456", "123")):
            for c, ch in enumerate(item):
                btn = Button(self, text=ch,
                             command=(lambda s=self, c=ch:s.update_expr(c)))
                btn.grid(row=r+1, column=c, padx=2, pady=2, sticky=NSEW)
        
        btn = Button(self, text="0", command=(lambda s=self, c="0":s.update_expr(c)))
        btn.grid(row=4, column=0, columnspan=2, padx=2, pady=2, sticky=NSEW)
        
        btn = Button(self, text=".", command=(lambda s=self, c=".":s.update_expr(c)))
        btn.grid(row=4, column=2, padx=2, pady=2, sticky=NSEW)
        
        
        
        """
        계산기 숫자 우측에 연산자 버튼 넣기
        """
        for r, ch in enumerate("/*-+"):
            btn = Button(self, text = ch, command=(lambda s=self, c=ch:s.update_expr(c)))
            btn.grid(row= r+1, column=3, padx = 2, pady = 2, sticky=NSEW)
        
        
        # C, = 버튼 넣기
        btn = Button(self, text="C", command=(lambda s=self, w=self.strExpr:w.set("")))
        btn.grid(row=1, column=4, rowspan=2, padx=2, pady=2, sticky=NSEW)
        btn = Button(self, text="=", command=(lambda s=self:s.calc()))
        btn.grid(row=3, column=4, rowspan=2, padx=2, pady=2, sticky=NSEW)

if __name__ == "__main__":
    Calculator().mainloop()

 

 

 

스톱워치 구현

 


from tkinter import Frame, Label, Entry, DoubleVar, W,\
                Tk, Button, StringVar, SUNKEN, NSEW, TOP, LEFT
import tkinter as tk
import time



def runTimer():
    global timer, start_time, elapsed_time, prev_elapsed_time
    if (running):
        cur_time = time.time()
        time_diff = cur_time - start_time
        elapsed_time = time_diff + prev_elapsed_time
        timeText.configure(text="{:7.3f}".format(elapsed_time))
    window.after(10, runTimer) # 10ms뒤에 runTimer 다시 호출

def start():
    global running, start_time, elapsed_time, prev_elapsed_time
    if (running !=True):
        running = True
        start_time = time.time()
        prev_elapsed_time = elapsed_time

def stop():
    global running, prev_elapsed_time, elapsed_time
    running = False
    prev_elapsed_time = elapsed_time

def reset():
    global running, timer, elapsed_time, prev_elapsed_time
    running = False
    elapsed_time = 0.0
    prev_elapsed_time = 0.0
    timeText.configure(text="{:7.3f}".format(elapsed_time))

window = Tk()
window.title("My Simple Stop watch")
running = False

timer = 0
start_time = stop_time = time.time()
prev_elapsed_time = elapsed_time = 0.0
timeText = Label(window, height = 5, text="0.000", font=("Arial 40 bold"))
timeText.pack(side=TOP)

startButton = Button(window, width=10, text="Start", bg="green", command=start)
startButton.pack(side = LEFT)
stopButton = Button(window, width=10, text="Stop", bg="red", command=stop)
stopButton.pack(side = LEFT)
resetButton = Button(window, width=10, text="Rest", bg="yellow", command=reset)
resetButton.pack(side = LEFT)

if __name__ == "__main__":
    runTimer()
    window.mainloop()

Tcl(tool command language)/Tk, tkinter

- Tcl :  웹, 데스트탑 어플, 네트워크, 테스팅 등 다양한 용도로 동적 프로그래밍 하기 좋은 언어

- Tk : GUI 라이브러리 제공하는 툴킷

- tkinter : Tcl/Tk 파이썬 레퍼로 tkinter 패키지로 gui 프로그래밍

 

 

1. tkinter window 관리 예제

- 윈도우 만들고, 크기 고정하고, X 누르면 메시지박스, iconify 버튼으로 아이콘화, quit버튼으로 종료

import tkinter
from tkinter import *
from tkinter import messagebox

global window

window = Tk()
window.title("window = Tk()")
window.geometry("300x300+100+100")
window.resizable(width=False, height = False)

def ask_quit():
    result = messagebox.askquestion("Msg", "quit?")
    if result == "yes":
        window.destroy()

label = Label(window, text="Buttons")
label.pack() # pack()윈도우에 배치
iconBtn = Button(window, text="iconify", command=window.iconify) #iconify 아이콘화
iconBtn.pack()
quitBtn = Button(window, text="quit", command=window.destroy)
quitBtn.pack()

window.protocol("WM_DELETE_WINDOW", ask_quit)
window.mainloop()

 

 

tkinter의 widget(window gadget) 클래스 

- tkinter의 위젯으로 frame, canvas가 있다.

- 하나의 윈도우에는 여러 프레임을 넣을 수 있다.

- 각 프레임에는 여러 캔버스를 넣을 수 있다.

- 각 캔버스에는 여러 라벨과 버튼 등의 위젯을 넣을 수 있다.

 

위젯 종류

- entry : 문자열 입력 공간

- scale : 슬라이드로 설정

- menu : 팝업 팝다운 메뉴

- 등

 

https://m.blog.naver.com/sisosw/221408280038

 

 

 

2. 윈도우 안에 프레임과 캔버스 그리기

import tkinter
from tkinter import *

window = Tk()
window.title("window - tk()")
window.geometry("600x600+200+100")
window.resizable(width=False, height=False)



frame1 = Frame(window, bg="light green", cursor="heart", bd=5, padx=10, pady=10, relief=GROOVE) #relief 프레임 기본 스타일
#relief : flat(기본), raised(버튼올린모양), sunken(버튼눌린모양), groove, ridge 등(대문자)
frame1.grid(row=0,column=0)
frame2 = Frame(window, bg="yellow", cursor="man", bd=5, padx=10, pady=10, relief=GROOVE)
frame2.grid(row=1,column=0)
frame3 = Frame(window, bg="yellow", cursor="plus", bd=5, padx=10, pady=10, relief=GROOVE)
frame3.grid(row=2, column=0)


canvas_11 = Canvas(frame1, bg="lime", width=100, height=100)
canvas_11.grid(row=0, column=0, fill=None, padx=10, pady=10)
canvas_12 = Canvas(frame1, bg="orange", width=150, height=100)
canvas_12.grid(row=0, column=1, fill=None, padx=10, pady=10)
canvas_13 = Canvas(frame1, bg="grey", width=100, height=100)
canvas_13.grid(row=1, column=1, fill=None, padx=10, pady=10)


canvas_21 = Canvas(frame2, bg="magenta", width=200, height=50)
canvas_21.grid(row=0, column=0, fill=None, padx=10, pady=10)
canvas_22 = Canvas(frame2, bg="brown", width=200, height=50)
canvas_22.grid(row=0, column=1, fill=None, padx=10, pady=10)
canvas_23 = Canvas(frame2, bg="sky blue", width=200, height=50)
canvas_23.grid(row=1, column=0, fill=None, padx=10, pady=10)

canvas_31 = Canvas(frame3, bg="light green", width=400, height=50)
canvas_31.grid(row=0, column=0, fill=None, padx=10, pady=10)
window.mainloop()

 

위젯 배치 layout

- 압축 배치 pack() : pack(fill=BOTH)  # fill= X, Y, BOTH  

- 격자 배치 grid() : grid(row=2, column=1)

- 절대 위치 배치 place() : place(x=200, y=200)

 

 

 

3. 압축 배치 연습

 

from tkinter import *

window =Tk()
window.title("testing pack layout")
window.geometry("400x300+100+200")



label1 = Label(window, text="label 1", bg="red", fg="white").pack(fill=X, padx=10, pady=10)
label2 = Label(window, text="label 2", bg="green", fg="black").pack(fill=X, padx=10, pady=10)
label3 = Label(window, text="label 3", bg="yellow", fg="white").pack(fill=X, padx=10, pady=10)

label4 = Label(window, text="label 4", bg="red", fg="black").pack(fill=X,padx=10, pady=10, side=LEFT)
label5 = Label(window, text="label 5", bg="green", fg="black").pack(fill=X, padx=10, pady=10, side=LEFT)
label6 = Label(window, text="label 6", bg="blue", fg="black").pack(fill=X, padx=10, pady=10, side=LEFT)

listbox = Listbox(window)
listbox.pack(fill=BOTH, expand=1)
L = [100, 200, 300, 400, 500]
for i in range(len(L)):
    listbox.insert(END, str(L[i]))

mainloop()

 

 

grid 함수

- column = 열, row = 행

- columnspan = 위젯이 차지하는 열 칸 수, rowspan = 위젯이 차지할 행칸 수

- in : 위젯이 놓일 위젯, 디폴트는 부모 위젯

- sticky : 위젯을 어떻게 붙일건지 디폴트는 중앙, NSEW는 셀 경계 딱붙인다.

 

entry 위젯 주요 함수

- focus() : 키보드 입력 가능하게 함

- bind() : 특정 이벤트시 실행 함수 바인드

 

 

 

 

4. 그리드 레이아웃과 엔트리 바인드

- window.bind()와 Button(command=())로 엔터키를 누르거나("<Return>"), 버튼누를시 fetch()함수 호출

 -> 엔터누르거나 fetch 버튼 클릭 시 fetch 함수대로 입력 데이터가 잘 출력된다.

from tkinter import *

def fetch(cells):
    print("- input data -")
    for i, e in enumerate(cells):
        print("  {0}:{1}".format(fields[i], e.get()))

def make_form(fields):
    cells = []
    for r, field in enumerate(fields):
        label = Label(window, width=10, text= field)
        entry = Entry(window)
        label.grid(row=r, column=0, sticky=NSEW)
        entry.grid(row=r, column=1, sticky=NSEW)
        cells.append(entry)
    return cells

if __name__ == "__main__":
    window = Tk()
    window.title("Input Dialog with label and entry")
    fields = ("Name", "Age", "Address")
    cells = make_form(fields)
    window.bind("<Return>", (lambda event, e=cells: fetch(e)))
    #엔터키 눌릴떼 람다식 호출 바인드
    #cells를 e에 담고 fetch 호출
    # 주의 : bind 함수 호출시 lambda 식 앞단에 인수를 2개해야한다.
    Button(window, text="Fetch", bg="green",
           command=(lambda e=cells:fetch(e))).grid(row=3, column=0, sticky=NSEW)
    # 버튼 눌릴때도 fetch(e) 호
    Button(window, text="Quit", bg="Red", command=window.destroy).grid(row=3, column=1, sticky=NSEW)
    print("grid size : ", window.grid_size())
    window.grid_columnconfigure(1, weight=1)
    window.grid_rowconfigure(0, weight=1)
    window.mainloop()

 

 

캔버스 객체의 함수들

- after(delay_ms, callback=None, *args) : 딜레이 타임 후 콜백함수 호출

- bind(sequence=None, func=None, add=None)  : 시퀀스 이벤트에 func 바인딩

- bind_all(csequence=None, func=None, add=None) : 모든 위젯에 func 바인딩

- bind_class(className, sequence=None, func=None, addd=None) : 해당 클래스 모든 위젯에 이벤트 func 바인딩

- create_image/line/oval/polygon/rectangle/text/window

- pos = canvas.coords(객체이름, pos) : 해당 객체 위치

- destroy() : 위젯과 객체제거

- mainloop() : 반복 시작

- quit() 반복 중지

- move(item, dx, dy) : 해당 아이템 객체를 이동

- update() 디스플레이 갱신

 

 

 

Event

- 버튼 : <Button-1>(마우스 왼쪽버튼 클릭), <Button-2> (마우스 휠 클릭), <button-3> (마우스 우클릭)

- 모션 : <Motion>(마우스 움직일때), <B1-Motion> 마우스 좌클릭채 움직일때, ...

- 위젯 동작 : <Configure> 위젯 모양 변경시, <Enter> 위젯안으로 마우스 들어갈때, <Leave> 위젯에서 나올때

- etc ...

 

 

 

 

5. 프레임, 캔버스 크기변경 이벤트 시 함수 호출

- 모든 위젯 크기 변경시 onsize 호출

- 그 중 위젯이 프레임일때 현재 크기반영해 라벨 변경

from tkinter import *

def onSize(event):
    if event.widget == frame: # 이벤트 호출된 위젯이 프레임인경우
        frame.update() # 라벨 변경전 갱신
        label_fr.configure(text="frame size: {}x{}".format(frame.winfo_width(), frame.winfo_height()))
        canvas.update()
        label_cnv.configure(text="canvas size: {}x{}".format(canvas.winfo_width(), canvas.winfo_height()))
    
    
if __name__ == "__main__":
    global label_Fr, label_cnv, frame, canvas
    window =Tk()
    window.title("finding frame and canvas size at resizing events")
    frame = Frame(window, bg="light green", bd=10, padx=50, pady=50, relief=GROOVE)
    frame.pack(expand=YES, fill=BOTH)
    canvas = Canvas(frame, bg="white", width=600, height=400)
    canvas.pack(expand=YES, fill=BOTH, padx=10, pady=10) #frame, canvas 양방향 조절 가능
    frame.update()
    label_fr = Label(canvas, text="frame size: {} x {}".format(frame.winfo_width(), frame.winfo_height()))
    label_fr.grid(row=0, column=0, sticky=N)
    canvas.update()
    label_cnv = Label(canvas, text="canvas size: {} x {}".format(canvas.winfo_width(), canvas.winfo_height()))
    label_cnv.grid(row=1, column=0, sticky=S)
    
    # <Configure> : 위젯모양변경시 이벤트 -> onSize() 호출
    # bind_all(컨피겨, func) -> 모든 위젯 크게 변경시 onsize() 호출 
    window.bind_all("<Configure>", onSize)
    window.mainloop()

 

 

 

 

+ 깃 로컬 저장소를 원격 저장소에 올리기

1. git init으로 깃 저장소 초기화

2. git add . 모든 파일 스태징

3. 커밋

 

4. git remote add origint 원격저장소 주소

5. git remote -v로 연결되었는지 확인

6. git push -u origit master 로컬 저장소 브랜치를 원격 저장소 master로 푸시(u는 지역과 원격 연결을 위해 한번만)

 

 

7. 깃헙에 잘올라갔다.

+ Recent posts