5강. 로그인 과제

0. 학습 목표
→ QTabWidget 기반 화면에서 하나의 회원 Model을 여러 View가 공유하는 과제를 이해합니다.
이번 과제에서 할 일
이번 과제에서는 QTabWidget큐탭위젯을 사용해서 탭이 있는 로그인 프로그램을 만듭니다.

탭은 로그인 View, 메인화면 View, 프로필 View로 나눕니다.
중요한 점은 각 View가 회원 정보를 따로 저장하지 않는 것입니다.
하나의 회원 Model모델을 만들고, 여러 View뷰가 같은 Model을 공유해야 합니다.
| 구분 | 내용 |
| 핵심 개념 | 회원 Model 하나를 기준으로 로그인 View, 메인화면 View, 프로필 View가 같은 데이터를 공유합니다. |
| 실습 준비 | PySide6, QTabWidget, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout을 사용합니다. |
| 최종 목표 | 로그인 후 메인화면과 프로필 화면에 같은 회원 정보가 출력되고, 프로필 수정 내용이 메인화면에도 반영되도록 구현합니다. |
| 제출 기한 | X월 X일 월요일까지 제출하세요. |
이번 과제의 핵심: View마다 회원 정보를 따로 만들지 말고, 하나의 MemberModel을 여러 View가 함께 사용하도록 구현해야 합니다.
1. 왜 하나의 회원 Model을 공유해야 할까?
→ 여러 화면이 같은 회원 정보를 보여주려면 데이터를 한 곳에서 관리해야 합니다.
1.1 이번 과제의 상황
이번 과제에서는 하나의 프로그램 안에 3개의 탭 화면을 만듭니다.
첫 번째 탭은 로그인 화면입니다.
두 번째 탭은 로그인한 회원 정보를 보여주는 메인화면입니다.
세 번째 탭은 회원 정보를 보여주고 수정하는 프로필 화면입니다.
# 탭 화면 구성
TabLayout
├── 로그인 View
├── 메인화면 View
└── 프로필 View
여기서 중요한 점은 메인화면 View와 프로필 View가 같은 회원 정보를 보여줘야 한다는 것입니다.
프로필 View에서 이름, 이메일, 전화번호를 수정하면 메인화면 View에도 수정된 값이 보여야 합니다.
| 탭 이름 | 역할 |
| 로그인 View | ID, PW를 입력하고 로그인 성공 여부를 확인합니다. |
| 메인화면 View | 로그인한 회원 정보를 출력합니다. |
| 프로필 View | 로그인한 회원 정보를 출력하고, 이름, 이메일, 전화번호를 수정합니다. |
1.2 View마다 데이터를 따로 저장하면 생기는 문제
처음에는 각 View 안에 회원 정보를 따로 넣고 싶을 수 있습니다.
하지만 이렇게 만들면 프로필 View에서 정보를 수정해도 메인화면 View의 정보는 바뀌지 않을 수 있습니다.
왜냐하면 두 View가 서로 다른 데이터를 가지고 있기 때문입니다.
# 기존 구조
LoginView
└── 로그인 정보 따로 저장
MainView
└── 회원 정보 따로 저장
ProfileView
└── 회원 정보 따로 저장
위 구조에서는 각 View가 자기 데이터를 따로 가지고 있습니다.
그래서 한 화면에서 데이터를 바꿔도 다른 화면에 바로 반영되기 어렵습니다.
1.3 하나의 Model을 공유하는 구조
이번 과제에서는 회원 정보를 MemberModel 하나에만 저장합니다.
그리고 로그인 View, 메인화면 View, 프로필 View가 같은 MemberModel을 바라보도록 만듭니다.
# 새 구조
MemberModel
└── 회원 정보 저장
LoginView
└── MemberModel 사용
MainView
└── MemberModel 사용
ProfileView
└── MemberModel 사용
이렇게 만들면 프로필 View에서 Model의 값을 바꿨을 때, 메인화면 View도 같은 Model에서 값을 다시 읽어올 수 있습니다.
즉, 여러 화면이 같은 회원 정보를 공유할 수 있습니다.
문제의 핵심: 여러 View가 같은 데이터를 보여줘야 한다면, 데이터는 View 안에 흩어두지 말고 하나의 Model에서 관리해야 합니다.
2. Tab 로그인 화면 구조 직접 설계하기
→ QTabWidget으로 3개의 View를 만들고, 회원 Model을 공유하는 구조를 설계합니다.
2.1 프로젝트 구조
프로젝트 구조는 자유롭게 만들 수 있지만, 아래 구조를 권장합니다.
처음에는 파일을 너무 많이 나누기보다, Model과 View 역할이 구분되도록 작성하는 것이 중요합니다.
# 권장 프로젝트 구조
tab_model_view_login/
├── main.py
├── member_model.py
└── tab_window.py
파일 역할은 다음과 같습니다.
| 파일 | 역할 |
| main.py | QApplication을 만들고 메인 윈도우를 실행합니다. |
| member_model.py | 회원 정보를 저장하고 로그인 검사, 정보 수정 기능을 담당합니다. |
| tab_window.py | QTabWidget을 사용해 로그인 View, 메인화면 View, 프로필 View를 구성합니다. |
2.2 회원 Model 구현 조건
먼저 회원 정보를 저장할 MemberModel을 구현합니다.
회원 정보는 View마다 따로 저장하지 않고, MemberModel 하나에만 저장해야 합니다.
| 필드명 | 설명 |
| id | 회원 아이디 |
| pw | 회원 비밀번호 |
| name | 회원 이름 |
| 회원 이메일 | |
| phone | 회원 전화번호 |
예시 회원 정보는 코드 안에 미리 만들어도 됩니다.
# 예시 회원 정보
member = {
"id": "test",
"pw": "1234",
"name": "홍길동",
"email": "test@test.com",
"phone": "010-1234-5678",
}
MemberModel에는 최소한 로그인 검사 기능과 회원 정보 수정 기능이 있어야 합니다.
| 기능 | 설명 |
| check_login(id, pw) | 입력한 ID와 PW가 Model의 정보와 일치하는지 확인합니다. |
| get_member_info() | 메인화면과 프로필 화면에서 출력할 회원 정보를 반환합니다. |
| update_profile(name, email, phone) | 프로필 View에서 수정한 이름, 이메일, 전화번호를 Model에 반영합니다. |
2.3 로그인 View 구현 조건
로그인 View에는 ID 입력칸, PW 입력칸, 로그인 버튼이 있어야 합니다.
로그인 버튼을 누르면 입력한 값과 MemberModel의 값을 비교합니다.
| 요소 | 조건 |
| ID 입력칸 | QLineEdit으로 구현합니다. |
| PW 입력칸 | QLineEdit으로 구현하고, 비밀번호처럼 보이도록 EchoMode를 설정할 수 있습니다. |
| 로그인 버튼 | clicked.connect(...)로 로그인 처리 함수와 연결합니다. |
로그인 성공 조건은 다음과 같습니다.
# 로그인 성공 조건
입력한 ID == 회원 Model의 ID
입력한 PW == 회원 Model의 PW
로그인에 성공하면 다음 동작을 수행합니다.
# 로그인 성공 후 동작
로그인 성공 메시지 출력
↓
메인화면 View 탭으로 이동
↓
메인화면 View에 회원 정보 출력
↓
프로필 View에도 같은 회원 정보 출력
로그인에 실패하면 로그인 실패 메시지를 출력하고, 로그인 View에 그대로 머무릅니다.
2.4 메인화면 View 구현 조건
메인화면 View에는 로그인한 회원 정보가 출력되어야 합니다.
출력해야 할 정보는 아이디, 이름, 이메일, 전화번호입니다.
# 메인화면 View 출력 예시
[메인화면] 로그인한 회원 정보
아이디: test
이름: 홍길동
이메일: test@test.com
전화번호: 010-1234-5678
주의할 점은 메인화면 View가 회원 정보를 직접 새로 만들면 안 된다는 것입니다.
반드시 MemberModel에 저장된 정보를 가져와서 출력해야 합니다.
2.5 프로필 View 구현 조건
프로필 View에는 로그인한 회원 정보가 출력되어야 합니다.
또한 이름, 이메일, 전화번호를 수정할 수 있어야 합니다.
# 프로필 View 예시
[프로필]
아이디: test
이름: [홍길동]
이메일: [test@test.com]
전화번호: [010-1234-5678]
[수정하기 버튼]
수정할 수 있는 정보는 다음 3개입니다.
| 수정 항목 | 설명 |
| 이름 | 회원 이름을 수정합니다. |
| 이메일 | 회원 이메일을 수정합니다. |
| 전화번호 | 회원 전화번호를 수정합니다. |
아이디와 비밀번호는 수정하지 않아도 됩니다.
수정 버튼을 누르면 MemberModel의 정보가 변경되어야 합니다.
핵심 확인: 프로필 View에서 수정한 값은 프로필 View 안에만 저장하는 것이 아니라 MemberModel에 반영해야 합니다.
3. 로그인부터 정보 수정까지 동작 흐름 살펴보기
→ 로그인 성공, 탭 이동, 프로필 수정, 메인화면 반영 흐름을 단계별로 정리합니다.
3.1 로그인 성공 흐름
로그인 버튼을 눌렀을 때 성공하면 다음 순서로 동작해야 합니다.
# 로그인 성공 흐름
로그인 View에서 ID, PW 입력
↓
로그인 버튼 클릭
↓
MemberModel의 ID, PW와 비교
↓
로그인 성공 메시지 출력
↓
메인화면 View 탭으로 이동
↓
메인화면 View에 회원 정보 출력
↓
프로필 View에도 회원 정보 출력
탭 이동은 QTabWidget의 현재 탭 인덱스를 변경하는 방식으로 구현할 수 있습니다.
예를 들어 로그인 탭이 0번, 메인화면 탭이 1번이라면 로그인 성공 후 1번 탭으로 이동하면 됩니다.
# 예시 코드
self.tab_widget.setCurrentIndex(1)
3.2 로그인 실패 흐름
로그인에 실패하면 탭을 이동하지 않습니다.
로그인 실패 메시지를 출력하고, 로그인 View에 그대로 머무릅니다.
# 로그인 실패 흐름
로그인 View에서 ID, PW 입력
↓
로그인 버튼 클릭
↓
MemberModel의 ID, PW와 비교
↓
ID 또는 PW 불일치
↓
로그인 실패 메시지 출력
↓
로그인 View에 그대로 머무름
로그인 실패 상태에서는 메인화면 View와 프로필 View에 회원 정보를 출력하지 않아도 됩니다.
3.3 프로필 수정 후 메인화면 반영 흐름
프로필 View에서 정보를 수정하면 MemberModel의 값이 바뀌어야 합니다.
그리고 메인화면 View는 그 바뀐 Model 값을 다시 읽어서 출력해야 합니다.
# 프로필 수정 흐름
프로필 View에서 이름, 이메일, 전화번호 수정
↓
[수정하기] 버튼 클릭
↓
MemberModel.update_profile() 호출
↓
MemberModel의 회원 정보 변경
↓
메인화면 View 출력 내용 갱신
↓
프로필 View 출력 내용 갱신
예를 들어 프로필 View에서 아래처럼 수정했다고 가정합니다.
# 수정 입력 예시
이름: 김철수
이메일: kim@test.com
전화번호: 010-9999-8888
수정 후 메인화면 View에는 아래처럼 변경된 정보가 보여야 합니다.
# 메인화면 변경 결과 예시
[메인화면] 로그인한 회원 정보
아이디: test
이름: 김철수
이메일: kim@test.com
전화번호: 010-9999-8888
이 결과가 보이면 메인화면 View와 프로필 View가 같은 MemberModel을 공유하고 있다는 뜻입니다.
주의할 점: 프로필 View에서 수정한 뒤 메인화면 View가 바뀌지 않는다면, View마다 회원 정보를 따로 저장하고 있는지 확인해야 합니다.
4. 구현 조건과 제출 전 체크리스트 정리하기
→ 과제에서 반드시 지켜야 할 조건과 제출 전 확인 항목을 정리합니다.
4.1 핵심 구현 조건
반드시 다음 조건을 지켜서 구현하세요.
| 번호 | 조건 |
| 1 | 회원 Model을 먼저 구현합니다. |
| 2 | 로그인 View에서 ID, PW를 입력받습니다. |
| 3 | 로그인 성공 시 메인화면 View 탭으로 이동합니다. |
| 4 | 메인화면 View에서 회원 정보를 출력합니다. |
| 5 | 프로필 View에서도 같은 회원 정보를 출력합니다. |
| 6 | 프로필 View에서 회원 정보를 수정할 수 있어야 합니다. |
| 7 | 프로필 View에서 수정한 정보가 메인화면 View에도 반영되어야 합니다. |
| 8 | 각 View가 따로 회원 정보를 저장하지 않고, 하나의 회원 Model을 공유해야 합니다. |
4.2 제출 전 확인 사항
제출하기 전에 아래 항목을 직접 확인하세요.
| 확인 항목 | 완료 |
| 로그인 View에 ID, PW 입력칸이 있는가? | □ |
| 로그인 버튼을 누르면 ID/PW 검사가 되는가? | □ |
| 로그인 성공 시 메인화면 View 탭으로 이동하는가? | □ |
| 메인화면 View에 회원 정보가 출력되는가? | □ |
| 프로필 View에도 같은 회원 정보가 출력되는가? | □ |
| 프로필 View에서 이름, 이메일, 전화번호를 수정할 수 있는가? | □ |
| 수정 후 메인화면 View에도 변경된 정보가 보이는가? | □ |
| 회원 정보가 View마다 따로 저장되지 않고 Model을 통해 공유되는가? | □ |
4.3 최종 제출 안내
이번 과제는 X월 1일 월요일까지 제출하세요.
제출 전에는 반드시 로그인 성공, 로그인 실패, 프로필 수정, 메인화면 반영까지 직접 실행해 봐야 합니다.
코드가 실행되는 것뿐 아니라, Model 하나를 여러 View가 공유하는 구조로 작성했는지도 확인해야 합니다.
기억할 문장: 이번 과제의 목표는 화면을 예쁘게 만드는 것이 아니라, 하나의 Model 데이터를 여러 View가 공유하는 구조를 이해하는 것입니다.
참고. 공식 문서와 참고 링크 확인하기
→ QTabWidget과 Model/View 구조를 더 공부할 수 있는 자료를 확인합니다.
참고 문서
QTabWidget과 Model/View 구조는 아래 자료를 참고하세요.
참고: 공식 Qt Model/View 구조는 QAbstractItemModel 같은 클래스를 사용하는 더 확장된 구조입니다. 이번 과제에서는 초보자용으로 하나의 회원 Model을 여러 View가 공유하는 방식에 집중합니다.