Model/View 로그인 구조 구현 정리

 

회원 정보는 MemberModel 하나에만 저장하고, 로그인 화면, 메인화면, 프로필 화면이 같은 Model을 바라보도록 구성하였다.

MemberModel
 └── 회원 정보 저장

Login View
 └── 로그인 검사

Main View
 └── 회원 정보 출력

Profile View
 └── 회원 정보 조회 및 수정

1. MemberModel 구현

MemberModel은 회원 정보를 저장하고 관리하는 Model 클래스이다. 아이디, 비밀번호, 이름, 이메일, 전화번호를 저장하며 프로그램 내에서는 하나의 Model만 사용하도록 구성하였다.

member_model.py

# 회원 정보를 저장하고 관리하는 Model 클래스
class MemberModel:

    # 객체가 생성될 때 자동으로 실행되는 생성자
    def __init__(self):

        # 회원 아이디 저장
        self.user_id = "test"

        # 회원 비밀번호 저장
        self.user_pw = "1234"

        # 회원 이름 저장
        self.name = "홍길동"

        # 회원 이메일 저장
        self.email = "test@test.com"

        # 회원 전화번호 저장
        self.phone = "010-1234-5678"

    # 로그인 검사를 위한 함수
    # 사용자가 입력한 아이디와 비밀번호를 전달받아
    # Model에 저장된 아이디, 비밀번호와 비교한다.
    def check_login(self, input_id, input_pw):

        # 입력한 아이디와 비밀번호가 모두 일치하면 로그인 성공
        if input_id == self.user_id and input_pw == self.user_pw:

            # 로그인 성공 결과를 Login View에 전달
            return True

        else:

            # 로그인 실패 결과를 Login View에 전달
            return False

    # 회원 정보를 반환하는 함수
    # Main View와 Profile View에서 회원 정보를 출력할 때 사용한다.
    def get_member_info(self):

        # 현재 Model에 저장된 회원 정보를 딕셔너리 형태로 반환한다.
        return {
            "id": self.user_id,
            "pw": self.user_pw,
            "name": self.name,
            "email": self.email,
            "phone": self.phone
        }

    # 회원 정보를 수정하는 함수
    # Profile View에서 수정한 이름, 이메일, 전화번호를 Model에 반영한다.
    def update_profile(self, name, email, phone):

        # 전달받은 이름으로 회원 이름 수정
        self.name = name

        # 전달받은 이메일로 회원 이메일 수정
        self.email = email

        # 전달받은 전화번호로 회원 전화번호 수정
        self.phone = phone

여기서 중요한 점은 View가 회원 정보를 직접 저장하지 않는다는 것이다. 모든 회원 정보는 MemberModel에서 관리한다.


2. Login View 구현

Login View는 사용자가 아이디와 비밀번호를 입력할 수 있는 화면이다. 로그인 버튼을 누르면 입력한 값과 MemberModel에 저장된 값을 비교한다.

login_view.py

from PySide6.QtWidgets import (
    QWidget,
    QVBoxLayout,
    QPushButton,
    QLabel,
    QLineEdit,
    QMessageBox
)


class Login(QWidget):

    def __init__(self, member_model, tab_widget, main_window):
        super().__init__()

        # main_window.py에서 전달받은 MemberModel 저장
        # 로그인 검사 시 사용한다.
        self.member_model = member_model

        # 탭 이동을 위해 QTabWidget 저장
        self.tab_widget = tab_widget

        # 로그인 성공 상태를 MainWindow에 전달하기 위해 저장
        self.main_window = main_window

        # 아이디 입력 라벨과 입력창 생성
        label_id = QLabel("아이디 :")
        self.line_edit_id = QLineEdit()
        self.line_edit_id.setPlaceholderText("아이디를 입력하세요")

        # 비밀번호 입력 라벨과 입력창 생성
        label_pw = QLabel("비밀번호 :")
        self.line_edit_pw = QLineEdit()
        self.line_edit_pw.setPlaceholderText("비밀번호를 입력하세요")

        # 비밀번호 입력값이 화면에 그대로 보이지 않도록 설정
        self.line_edit_pw.setEchoMode(QLineEdit.EchoMode.Password)

        # 로그인 버튼 생성
        login_button = QPushButton("로그인")

        # 버튼 클릭 시 login_button_clicked 함수 실행
        login_button.clicked.connect(self.login_button_clicked)

        # 세로 레이아웃 생성
        layout = QVBoxLayout()

        # 레이아웃에 위젯 추가
        layout.addWidget(label_id)
        layout.addWidget(self.line_edit_id)
        layout.addWidget(label_pw)
        layout.addWidget(self.line_edit_pw)
        layout.addWidget(login_button)

        # 현재 Login View에 레이아웃 적용
        self.setLayout(layout)

    # 로그인 버튼을 눌렀을 때 실행되는 함수
    def login_button_clicked(self):

        # 아이디 입력창에 입력된 값을 가져온다.
        input_id = self.line_edit_id.text()

        # 비밀번호 입력창에 입력된 값을 가져온다.
        input_pw = self.line_edit_pw.text()

        # MemberModel의 check_login 함수로 로그인 성공 여부 확인
        if self.member_model.check_login(input_id, input_pw):

            # 로그인 성공 팝업 출력
            QMessageBox.information(
                self,
                "로그인 성공",
                "로그인에 성공하였습니다."
            )

            # MainWindow의 로그인 상태를 True로 변경
            self.main_window.is_login = True

            # 로그인 성공 후 메인화면 탭으로 이동
            self.tab_widget.setCurrentIndex(1)

        else:

            # 로그인 실패 팝업 출력
            QMessageBox.warning(
                self,
                "로그인 실패",
                "아이디 또는 비밀번호가 올바르지 않습니다."
            )

            # 입력된 아이디와 비밀번호 삭제
            self.line_edit_id.clear()
            self.line_edit_pw.clear()

            # 다시 아이디 입력창에 커서 위치
            self.line_edit_id.setFocus()

QLineEdit.EchoMode.Password는 비밀번호 입력창에서 사용한다. 사용자가 입력한 문자를 그대로 보여주지 않고 점이나 별표 형태로 표시한다.


3. Main View 구현

Main View는 로그인 성공 후 회원 정보를 출력하는 화면이다. 아이디, 이름, 이메일, 전화번호를 MemberModel에서 가져와 QLabel에 출력한다.

main_view.py

from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel


class MainView(QWidget):

    def __init__(self, member_model, parent=None):
        super().__init__(parent)

        # main_window.py에서 전달받은 MemberModel 저장
        self.member_model = member_model

        # 세로 레이아웃 생성
        layout = QVBoxLayout()

        # 메인화면 제목
        title_label = QLabel("회원 정보")

        # 회원 정보를 출력할 QLabel 생성
        self.label_id = QLabel()
        self.label_name = QLabel()
        self.label_email = QLabel()
        self.label_phone = QLabel()

        # 레이아웃에 위젯 추가
        layout.addWidget(title_label)
        layout.addWidget(self.label_id)
        layout.addWidget(self.label_name)
        layout.addWidget(self.label_email)
        layout.addWidget(self.label_phone)

        # 현재 위젯에 레이아웃 적용
        self.setLayout(layout)

        # 처음 화면이 생성될 때 Model에 저장된 회원 정보를 출력
        self.update_view()

    # Model의 회원 정보를 화면에 출력하는 함수
    def update_view(self):

        # MemberModel에서 회원 정보를 가져온다.
        info = self.member_model.get_member_info()

        # 가져온 회원 정보를 QLabel에 출력한다.
        self.label_id.setText(f"아이디: {info['id']}")
        self.label_name.setText(f"이름: {info['name']}")
        self.label_email.setText(f"이메일: {info['email']}")
        self.label_phone.setText(f"전화번호: {info['phone']}")

update_view() 함수는 화면을 다시 갱신할 때 사용한다. 프로필 화면에서 회원 정보를 수정한 뒤 이 함수를 다시 실행하면, 메인화면에도 수정된 회원 정보가 출력된다.


4. Profile View 구현

Profile View는 회원 정보를 조회하고 수정할 수 있는 화면이다. 이름, 이메일, 전화번호를 수정할 수 있으며, 수정된 값은 Profile View 안에만 저장하지 않고 MemberModel에 반영한다.

profile_view.py

from PySide6.QtWidgets import (
    QWidget,
    QVBoxLayout,
    QLabel,
    QLineEdit,
    QPushButton,
    QMessageBox
)


class ProfileView(QWidget):

    def __init__(self, member_model, main_view, tab_widget, parent=None):
        super().__init__(parent)

        # main_window.py에서 전달받은 MemberModel 저장
        # 회원 정보를 조회하거나 수정할 때 사용한다.
        self.member_model = member_model

        # main_window.py에서 전달받은 MainView 저장
        # 프로필 수정 후 메인화면을 갱신할 때 사용한다.
        self.main_view = main_view

        # 수정 완료 후 메인화면 탭으로 이동하기 위해 저장
        self.tab_widget = tab_widget

        # 세로 레이아웃 생성
        layout = QVBoxLayout()

        # 프로필 화면 제목
        title_label = QLabel("회원 정보 수정")

        # 아이디는 수정하지 않고 출력만 한다.
        self.label_id = QLabel()

        # 수정 가능한 입력창 생성
        self.line_edit_name = QLineEdit()
        self.line_edit_email = QLineEdit()
        self.line_edit_phone = QLineEdit()

        # 수정 버튼 생성
        update_button = QPushButton("수정하기")

        # 수정 버튼 클릭 시 update_button_clicked 함수 실행
        update_button.clicked.connect(self.update_button_clicked)

        # 레이아웃에 위젯 추가
        layout.addWidget(title_label)
        layout.addWidget(self.label_id)

        layout.addWidget(QLabel("이름"))
        layout.addWidget(self.line_edit_name)

        layout.addWidget(QLabel("이메일"))
        layout.addWidget(self.line_edit_email)

        layout.addWidget(QLabel("전화번호"))
        layout.addWidget(self.line_edit_phone)

        layout.addWidget(update_button)

        # 현재 Profile View에 레이아웃 적용
        self.setLayout(layout)

        # 화면 생성 시 Model에 저장된 회원 정보를 입력창에 출력
        self.update_view()

    # Model의 회원 정보를 프로필 화면에 출력하는 함수
    def update_view(self):

        # MemberModel에서 회원 정보 가져오기
        info = self.member_model.get_member_info()

        # 아이디는 QLabel에 출력
        self.label_id.setText(f"아이디: {info['id']}")

        # 이름, 이메일, 전화번호는 수정 가능하도록 QLineEdit에 출력
        self.line_edit_name.setText(info["name"])
        self.line_edit_email.setText(info["email"])
        self.line_edit_phone.setText(info["phone"])

    # 수정하기 버튼을 눌렀을 때 실행되는 함수
    def update_button_clicked(self):

        # 입력창에 입력된 값을 가져온다.
        name = self.line_edit_name.text()
        email = self.line_edit_email.text()
        phone = self.line_edit_phone.text()

        # Profile View에서 입력한 값을 MemberModel에 반영한다.
        self.member_model.update_profile(name, email, phone)

        # 프로필 화면을 다시 갱신한다.
        self.update_view()

        # 메인화면도 같은 MemberModel을 사용하므로 다시 갱신한다.
        self.main_view.update_view()

        # 수정 완료 팝업 출력
        QMessageBox.information(
            self,
            "수정 완료",
            "회원 정보가 수정되었습니다."
        )

        # 수정 후 메인화면 탭으로 이동
        self.tab_widget.setCurrentIndex(1)

        # 터미널 확인용 출력
        print("회원 정보가 수정되었습니다.")

5. 구현 흐름 정리

1. Login View에서 아이디와 비밀번호 입력

2. 로그인 버튼 클릭

3. MemberModel의 check_login() 함수로 로그인 검사

4. 로그인 성공 시 Main View로 이동

5. Main View는 MemberModel의 회원 정보를 출력

6. Profile View에서 이름, 이메일, 전화번호 수정

7. update_profile() 함수로 MemberModel 정보 수정

8. Main View의 update_view() 함수 실행

9. 메인화면에도 수정된 회원 정보 출력

6. 핵심 정리

  • 회원 정보는 View마다 따로 저장하지 않는다.
  • 회원 정보는 MemberModel 하나에서만 관리한다.
  • Login View는 로그인 입력과 검사 요청을 담당한다.
  • Main View는 회원 정보를 출력하는 역할을 담당한다.
  • Profile View는 회원 정보를 수정하는 역할을 담당한다.
  • 프로필에서 수정한 값은 MemberModel에 반영된다.
  • Main View는 다시 Model을 읽어 수정된 정보를 출력한다.
Model은 데이터를 관리하고, View는 데이터를 화면에 보여주는 역할을 담당한다.
여러 View가 같은 데이터를 사용해야 한다면, 데이터는 View 안에 흩어두지 않고 하나의 Model에서 관리해야 한다.

 

 

스크린캐스트 2026-06-01 15-43-55.webm
0.63MB

'개발일지 > python' 카테고리의 다른 글

Model/View  (0) 2026.05.29
객체지향 프로그래밍(OOP) 핵심 개념 총정리  (0) 2026.05.28
[Python] QScrollArea  (0) 2026.05.27
[Python] PySide6 QTabWidget 실습 / 파일 분리  (0) 2026.05.22
[숙제] 상속 예제 정리  (0) 2026.05.17