Tkinter 화면을 Vue 화면으로 변환

PYTHON → VUE
Chapter 11. Tkinter 화면을 Vue 화면으로 변환
Python Tkinter로 만들던 데스크톱 화면을
Vue의 데이터 중심 웹 화면으로 바꾸는 방법을 배웁니다.
Tkinter 프로그램을 Vue 웹 프로그램으로 변환하는 개발 환경
데스크톱 GUI의 개념을 버리는 것이 아니라, 익숙한 Tkinter 개념을 Vue 방식으로 다시 연결해 봅니다.
11.1 Python 프로그램을 웹 프로그램으로 변경하기

지금까지 Python에서는 Tkinter를 이용하여 데스크톱 프로그램의 화면을 만들었습니다.

Python 프로그램
Tkinter 화면 → Python 함수 → SQLite

이 프로그램을 웹 프로그램으로 변경하면 다음과 같은 구조가 됩니다.

웹 프로그램
Vue → REST API → FastAPI → SQLite
Tkinter 화면
데스크톱 GUI
Vue 화면
웹 UI
💡 이번 장의 핵심

Python 프로그램 전체를 한 번에 바꾸는 것이 아니라, 먼저 Tkinter 화면을 Vue 화면으로 변경하는 방법부터 이해합니다.

11.2 Tkinter와 Vue 비교

Tkinter와 Vue는 사용하는 문법은 다르지만 화면을 만드는 기본 개념에는 비슷한 부분이 많습니다.

Tkinter Vue / Web
Tk()웹 페이지 / App
FrameComponent / View
Label<label>, <p>, <span>
Entry<input>
Text<textarea>
Button<button>
Combobox<select>
Checkbutton<input type="checkbox">
Radiobutton<input type="radio">
Treeview<table> + v-for
command@click
StringVarref() 또는 reactive()
Frame 전환Vue Router
messageboxalert(), confirm()
💡 기존 지식을 활용하세요

새로운 개념을 처음부터 모두 배우는 것이 아니라 기존 Tkinter의 화면 개념을 웹 방식으로 바꾸어 생각하면 됩니다.

Python과 Vue 코드를 비교하며 개발하는 모습
같은 기능도 데스크톱 GUI와 웹에서는 표현 방법이 다릅니다. 핵심은 기능을 기준으로 대응 관계를 찾는 것입니다.
11.3 가장 간단한 화면 변환
Tkinter
Python
import tkinter as tk

window = tk.Tk()
window.title("사원관리")

label = tk.Label(
    window,
    text="사원관리 프로그램"
)

label.pack()

window.mainloop()
화면 결과
사원관리 프로그램
Vue
Vue
<template>
  <div>
    <h1>
      사원관리 프로그램
    </h1>
  </div>
</template>
Tkinter
Label → 화면에 문자열 표시
Vue
<h1> → 화면에 문자열 표시

Vue에서는 Tkinter 위젯 대신 웹의 HTML 태그를 이용하여 화면을 만듭니다.

11.4 Label을 Vue로 변경하기
Tkinter
Python
label = tk.Label(
    window,
    text="이름"
)

label.pack()
Vue
Vue
<template>
  <label>
    이름
  </label>
</template>

상황에 따라 다음과 같이 사용할 수도 있습니다.

HTML
<p>
  이름
</p>
Tkinter Label → label / p / span / h1 / h2
11.5 Entry를 Vue input으로 변경하기

Tkinter에서 문자열을 입력받을 때는 Entry를 사용합니다.

Tkinter
entry_name = tk.Entry(window)
entry_name.pack()

Vue에서는 HTML의 input을 사용합니다.

Vue
<input>

실제 프로그램에서는 입력값을 변수와 연결해야 합니다.

Tkinter 데이터 연결
Tkinter
name = tk.StringVar()

entry_name = tk.Entry(
    window,
    textvariable=name
)

entry_name.pack()
Vue 데이터 연결
Vue
<script setup>
import { ref } from 'vue'

const name = ref('')
</script>

<template>
  <input v-model="name">
</template>
Tkinter : StringVar ↔ Entry
Vue : ref ↔ input + v-model
대응 관계

StringVar → ref()
textvariable → v-model

11.6 Entry 값 가져오기
Tkinter
Entry 직접 사용
name = entry_name.get()
print(name)
StringVar 사용
print(name.get())
Vue
ref 값 사용
console.log(name.value)
entry_name.get() → name.value
💡 Vue의 중요한 방식

Vue에서는 화면의 input 요소를 직접 찾아 값을 가져오는 방식보다 v-model로 연결된 데이터를 사용하는 방식이 기본입니다.

11.7 Button 변환하기
Tkinter
Python
def save():
    print("저장")


button = tk.Button(
    window,
    text="저장",
    command=save
)

button.pack()
Vue
Vue
<script setup>
function save() {
  console.log('저장')
}
</script>

<template>
  <button @click="save">
    저장
  </button>
</template>
command=save → @click="save"

문법은 다르지만 버튼을 클릭했을 때 함수를 실행한다는 원리는 같습니다.

11.8 입력 + 버튼 프로그램 변환
Tkinter 프로그램
Python
import tkinter as tk
from tkinter import messagebox

window = tk.Tk()
window.title("사원등록")

tk.Label(
    window,
    text="이름"
).pack()

entry_name = tk.Entry(window)
entry_name.pack()


def save():
    name = entry_name.get()

    messagebox.showinfo(
        "확인",
        name
    )


tk.Button(
    window,
    text="등록",
    command=save
).pack()

window.mainloop()
Vue 프로그램
Vue
<script setup>
import { ref } from 'vue'

const name = ref('')

function save() {
  alert(name.value)
}
</script>

<template>
  <div>

    <label>
      이름
    </label>

    <input v-model="name">

    <button @click="save">
      등록
    </button>

  </div>
</template>
Tkinter Vue
Entryinput
StringVarref
textvariablev-model
Buttonbutton
command@click
messagebox.showinfoalert
11.9 여러 개의 입력창 변환

사원정보처럼 서로 관련된 입력값이 여러 개라면 Vue의 reactive() 객체로 묶어 관리할 수 있습니다.

Tkinter
Python
import tkinter as tk

window = tk.Tk()

tk.Label(
    window,
    text="이름"
).pack()

entry_name = tk.Entry(window)
entry_name.pack()

tk.Label(
    window,
    text="전화번호"
).pack()

entry_phone = tk.Entry(window)
entry_phone.pack()

tk.Label(
    window,
    text="부서"
).pack()

entry_department = tk.Entry(window)
entry_department.pack()

window.mainloop()
Vue
Vue
<script setup>
import { reactive } from 'vue'

const employee = reactive({
  name: '',
  phone: '',
  department: ''
})
</script>

<template>
  <div>

    <p>
      이름 :
      <input
        v-model="employee.name"
      >
    </p>

    <p>
      전화번호 :
      <input
        v-model="employee.phone"
      >
    </p>

    <p>
      부서 :
      <input
        v-model="employee.department"
      >
    </p>

  </div>
</template>
employee ├─ name ├─ phone └─ department
11.10 Combobox를 select로 변경하기
Tkinter
Python
from tkinter import ttk

department = tk.StringVar()

combo = ttk.Combobox(
    window,
    textvariable=department
)

combo["values"] = (
    "개발팀",
    "영업팀",
    "관리팀"
)

combo.pack()
Vue
Vue / HTML
<select
  v-model="employee.department"
>

  <option value="개발팀">
    개발팀
  </option>

  <option value="영업팀">
    영업팀
  </option>

  <option value="관리팀">
    관리팀
  </option>

</select>
ttk.Combobox → <select> + <option>
11.11 Text를 textarea로 변경하기
Tkinter
Python
text_memo = tk.Text(
    window,
    width=40,
    height=10
)

text_memo.pack()
Vue
Vue
<textarea
  v-model="employee.memo"
>
</textarea>
데이터
const employee = reactive({
  name: '',
  phone: '',
  department: '',
  memo: ''
})
11.12 Checkbutton 변환하기
Tkinter
Python
agree = tk.BooleanVar()

check = tk.Checkbutton(
    window,
    text="동의합니다.",
    variable=agree
)

check.pack()
Vue
Vue
<input
  type="checkbox"
  v-model="agree"
>

동의합니다.
데이터
const agree = ref(false)
BooleanVar → ref(false)
Checkbutton → checkbox
11.13 Radiobutton 변환하기
Tkinter
Python
gender = tk.StringVar()

tk.Radiobutton(
    window,
    text="남",
    variable=gender,
    value="남"
).pack()

tk.Radiobutton(
    window,
    text="여",
    variable=gender,
    value="여"
).pack()
Vue
Vue
<input
  type="radio"
  value="남"
  v-model="gender"
>
남

<input
  type="radio"
  value="여"
  v-model="gender"
>
여
데이터
const gender = ref('')
11.14 Treeview를 Vue table로 변경하기

사원관리 프로그램에서 가장 많이 사용하는 화면 중 하나는 여러 데이터를 표시하는 목록 화면입니다.

Tkinter Treeview
Python
from tkinter import ttk

tree = ttk.Treeview(
    window,
    columns=(
        "id",
        "name",
        "department"
    ),
    show="headings"
)

tree.heading(
    "id",
    text="번호"
)

tree.heading(
    "name",
    text="이름"
)

tree.heading(
    "department",
    text="부서"
)

tree.pack()

Treeview에 데이터를 추가할 때는 다음과 같이 작성합니다.

Treeview 데이터 추가
tree.insert(
    "",
    "end",
    values=(
        1,
        "홍길동",
        "개발팀"
    )
)
Vue table + v-for
Vue
<script setup>
import { ref } from 'vue'

const employees = ref([
  {
    id: 1,
    name: '홍길동',
    department: '개발팀'
  },
  {
    id: 2,
    name: '김철수',
    department: '영업팀'
  }
])
</script>

<template>

  <table border="1">

    <thead>
      <tr>
        <th>번호</th>
        <th>이름</th>
        <th>부서</th>
      </tr>
    </thead>

    <tbody>

      <tr
        v-for="emp in employees"
        :key="emp.id"
      >

        <td>
          {{ emp.id }}
        </td>

        <td>
          {{ emp.name }}
        </td>

        <td>
          {{ emp.department }}
        </td>

      </tr>

    </tbody>

  </table>

</template>
Tkinter : Treeview → tree.insert()
Vue : employees 배열 → v-for → table
웹 인터페이스의 데이터를 코드로 관리하는 개발 환경
Vue에서는 화면 요소 자체보다 화면을 만들어 내는 데이터를 변경하는 방식이 중요합니다.
11.15 목록에 데이터를 추가하는 방법
Tkinter
Treeview에 직접 추가
tree.insert(
    "",
    "end",
    values=(
        3,
        "이영희",
        "관리팀"
    )
)

Tkinter에서는 화면의 Treeview 위젯에 직접 데이터를 추가합니다.

Vue
배열에 데이터 추가
employees.value.push({
  id: 3,
  name: '이영희',
  department: '관리팀'
})

Vue에서는 배열의 데이터를 변경합니다. 그러면 v-for로 연결된 화면이 자동으로 갱신됩니다.

Tkinter
Treeview에 항목 추가
→ 화면 변경
Vue
배열에 데이터 추가
→ 반응형 데이터 변경
→ 화면 자동 변경
⚠ 매우 중요한 차이

Vue에서는 먼저 화면을 바꾸려고 하지 않습니다. 데이터를 변경하면 Vue가 화면을 자동으로 갱신한다고 생각해야 합니다.

11.16 목록에서 데이터를 삭제하는 방법
Tkinter
Treeview 항목 삭제
selected = tree.selection()

tree.delete(
    selected[0]
)
Vue
데이터 배열에서 삭제
function removeEmployee(id) {

  employees.value =
    employees.value.filter(
      emp => emp.id !== id
    )

}
화면
<button
  @click="
    removeEmployee(emp.id)
  "
>
  삭제
</button>
Tkinter : 화면 항목을 찾아 삭제
Vue : 데이터 삭제 → 화면 자동 변경
11.17 Frame을 컴포넌트로 변경하기

Tkinter 프로그램이 커지면 Frame을 사용하여 화면을 여러 영역으로 나눌 수 있습니다.

Main Window ├─ MenuFrame ├─ EmployeeFormFrame └─ EmployeeListFrame

Vue에서는 이와 비슷하게 Component를 이용합니다.

App.vue ├─ Menu.vue ├─ EmployeeForm.vue └─ EmployeeList.vue
App.vue
<script setup>
import EmployeeForm
  from './components/EmployeeForm.vue'

import EmployeeList
  from './components/EmployeeList.vue'
</script>

<template>
  <EmployeeForm />
  <EmployeeList />
</template>
Tkinter Frame → Vue Component
11.18 여러 화면 전환하기

Tkinter에서는 여러 Frame을 만들고 필요한 Frame을 표시하는 방식으로 화면을 전환할 수 있습니다.

Main Window ├─ 메인화면 Frame ├─ 사원목록 Frame └─ 사원등록 Frame

Vue에서는 각 화면을 View로 만들고 Vue Router로 전환합니다.

views ├─ HomeView.vue ├─ EmployeeListView.vue └─ EmployeeCreateView.vue
URL 화면
/
/employees사원목록
/employees/new사원등록
Tkinter Frame 전환 → Vue Router
11.19 messagebox 변환하기
정보 알림
Tkinter
from tkinter import messagebox

messagebox.showinfo(
    "확인",
    "저장되었습니다."
)
Vue / JavaScript
alert(
  '저장되었습니다.'
)
삭제 확인
Tkinter
result = messagebox.askyesno(
    "확인",
    "삭제하시겠습니까?"
)
Vue / JavaScript
const result = confirm(
  '삭제하시겠습니까?'
)
💡 실제 프로젝트에서는

교육 단계에서는 alert()와 confirm()을 사용하고, 실제 프로젝트에서는 별도의 알림창 또는 모달 컴포넌트로 변경할 수 있습니다.

11.20 Tkinter 사원등록 화면 전체 예제
Python / Tkinter
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox

window = tk.Tk()

window.title(
    "사원관리 프로그램"
)


tk.Label(
    window,
    text="이름"
).grid(
    row=0,
    column=0
)

entry_name = tk.Entry(window)

entry_name.grid(
    row=0,
    column=1
)


tk.Label(
    window,
    text="전화번호"
).grid(
    row=1,
    column=0
)

entry_phone = tk.Entry(window)

entry_phone.grid(
    row=1,
    column=1
)


tk.Label(
    window,
    text="부서"
).grid(
    row=2,
    column=0
)

combo_department = ttk.Combobox(
    window,
    values=(
        "개발팀",
        "영업팀",
        "관리팀"
    )
)

combo_department.grid(
    row=2,
    column=1
)


def save():

    name = entry_name.get()
    phone = entry_phone.get()

    department = (
        combo_department.get()
    )

    print(
        name,
        phone,
        department
    )

    messagebox.showinfo(
        "확인",
        "등록되었습니다."
    )


tk.Button(
    window,
    text="등록",
    command=save
).grid(
    row=3,
    column=0,
    columnspan=2
)


window.mainloop()

이제 이 Tkinter 화면과 동일한 기능을 Vue 방식으로 다시 구성해 보겠습니다.

11.21 Vue 사원등록 화면
Vue
<script setup>
import { reactive } from 'vue'


const employee = reactive({
  name: '',
  phone: '',
  department: '개발팀'
})


function save() {

  console.log(
    employee.name,
    employee.phone,
    employee.department
  )

  alert(
    '등록되었습니다.'
  )

}
</script>


<template>

  <div>

    <h2>
      사원등록
    </h2>

    <p>
      이름 :

      <input
        v-model="employee.name"
      >
    </p>

    <p>
      전화번호 :

      <input
        v-model="employee.phone"
      >
    </p>

    <p>
      부서 :

      <select
        v-model="employee.department"
      >

        <option value="개발팀">
          개발팀
        </option>

        <option value="영업팀">
          영업팀
        </option>

        <option value="관리팀">
          관리팀
        </option>

      </select>

    </p>

    <button @click="save">
      등록
    </button>

  </div>

</template>
💡 기능은 거의 같습니다

Tkinter와 Vue 모두 이름, 전화번호, 부서를 입력하고 등록 버튼을 누르는 기능을 구현합니다. 차이는 화면과 데이터를 관리하는 방법입니다.

11.22 Tkinter와 Vue 코드 대응
이름 입력
Tkinter
entry_name = tk.Entry(window)
Vue
<input v-model="employee.name">
값 읽기
Tkinter
name = entry_name.get()
Vue
employee.name
버튼
Tkinter
command=save
Vue
@click="save"
콤보박스
Tkinter
ttk.Combobox(...)
Vue
<select v-model="employee.department">
11.23 화면 배치 방식의 차이

Tkinter에서는 다음과 같은 배치 관리자를 사용했습니다.

Tkinter 배치 관리자
pack()
grid()
place()
place 예
button.place(
    x=100,
    y=200
)

웹에서는 일반적으로 CSS를 이용해 화면을 배치합니다.

Vue
<template>
  <div class="form">

    <input>

    <button>
      등록
    </button>

  </div>
</template>

<style scoped>
.form {
  display: flex;
  gap: 10px;
}
</style>
Tkinter : pack / grid / place

Web : CSS / Flexbox / Grid

Vue는 화면의 데이터와 동작을 관리하고, 실제 배치는 HTML과 CSS가 담당합니다.

11.24 가장 중요한 차이

Tkinter 프로그램에서는 위젯을 직접 다루는 코드가 많이 사용됩니다.

Tkinter 방식
entry_name.get()

entry_name.delete(
    0,
    tk.END
)

tree.insert(...)

tree.delete(...)
화면 위젯 → 직접 조작

Vue에서는 화면 자체보다 데이터 중심으로 생각합니다.

Vue 방식
employee.name = ''

employees.value.push(
    newEmployee
)
데이터 변경 → Vue → 화면 자동 변경
⭐ 이 장에서 가장 중요한 개념

Tkinter에서는 위젯을 직접 조작하는 경우가 많지만, Vue에서는 데이터를 변경하면 화면이 자동으로 변경됩니다.

이 사고방식의 차이를 이해하는 것이 Tkinter 프로그램을 Vue로 변경할 때 가장 중요합니다.

11.25 화면 변환 순서

기존 Tkinter 프로그램을 Vue로 변경할 때는 다음 순서로 진행하면 이해하기 쉽습니다.

1
Tkinter 화면 확인
현재 화면에 어떤 입력창, 버튼, 목록이 있는지 먼저 확인합니다.
2
View와 Component로 구분
하나의 화면인지, 재사용할 부분인지 구분합니다.
3
Label → HTML
Label을 label, p, span, h1 등의 HTML 태그로 변경합니다.
4
Entry → input + v-model
입력창과 Vue 데이터를 연결합니다.
5
Button command → @click
버튼 클릭 이벤트를 Vue 방식으로 변경합니다.
6
Treeview → table + v-for
목록을 배열 데이터와 반복 렌더링 방식으로 변경합니다.
7
Frame → Component
화면을 Vue 컴포넌트 구조로 나눕니다.
8
여러 화면 전환 → Vue Router
URL을 이용해 목록, 등록, 상세 등의 화면을 전환합니다.
💡 코드를 한 줄씩 번역하지 않습니다

중요한 것은 Python 코드를 한 줄씩 JavaScript나 Vue 코드로 바꾸는 것이 아닙니다. 기존 화면이 제공하던 기능을 Vue 방식으로 다시 구성하는 것입니다.

Tkinter → Vue 핵심 대응표
Tkinter Vue / Web 의미
Tk() App / 웹 페이지 프로그램 기본 화면
Frame Component / View 화면 분리
Label label / p / span 문자 표시
Entry input 한 줄 입력
Text textarea 여러 줄 입력
Combobox select 선택 목록
Checkbutton checkbox 체크 입력
Radiobutton radio 하나 선택
Treeview table + v-for 목록 출력
StringVar ref() 반응형 단일 데이터
여러 변수 reactive() 관련 데이터 묶음
textvariable v-model 화면과 데이터 연결
command @click 버튼 이벤트
messagebox.showinfo alert() 알림
messagebox.askyesno confirm() 확인
Frame 전환 Vue Router 화면 이동
pack / grid / place CSS / Flexbox / Grid 화면 배치
📌 Chapter 11 핵심 정리
  • 기존 Python 프로그램의 Tkinter 화면은 Vue 화면으로 변경할 수 있습니다.
  • Tkinter의 Label은 HTML의 label, p, span 등의 태그로 표현합니다.
  • Tkinter의 Entry는 Vue에서 input으로 변경합니다.
  • StringVar와 textvariable의 역할은 Vue의 ref()와 v-model로 연결해서 생각할 수 있습니다.
  • 여러 개의 관련 입력값은 reactive() 객체로 묶어 관리할 수 있습니다.
  • Tkinter의 command는 Vue에서 @click 이벤트로 변경합니다.
  • Combobox는 select, Text는 textarea로 변경할 수 있습니다.
  • Checkbutton은 checkbox, Radiobutton은 radio로 표현합니다.
  • Treeview 목록은 Vue에서 table + 배열 + v-for 구조로 만들 수 있습니다.
  • Tkinter에서는 Treeview에 데이터를 직접 추가하지만 Vue에서는 배열 데이터를 변경하면 화면이 자동으로 갱신됩니다.
  • Tkinter의 Frame은 Vue의 Component 또는 View와 연결해서 이해할 수 있습니다.
  • 여러 Frame을 바꾸어 표시하던 방식은 Vue에서 Vue Router를 이용한 화면 전환으로 변경할 수 있습니다.
  • messagebox.showinfo는 교육 단계에서 alert()로 처리할 수 있습니다.
  • messagebox.askyesno는 confirm()으로 처리할 수 있습니다.
  • Tkinter의 pack, grid, place와 같은 배치는 웹에서는 CSS, Flexbox, Grid가 담당합니다.
  • Tkinter는 위젯을 직접 조작하는 방식이 많지만, Vue는 데이터를 변경하여 화면을 자동으로 갱신하는 방식이 핵심입니다.
  • Tkinter 코드를 한 줄씩 Vue 코드로 번역하는 것이 아니라 기존 화면의 기능을 Vue 방식으로 다시 구성해야 합니다.

프로그램·홈페이지·강의가 필요하신가요?

프로그램 판매, 무료 다운로드, 홈페이지 제작, IT 강의 상담을 도와드립니다.

상담 신청하기