개인 프로젝트/Accounting Program

#16 화주 삭제, 화주 이름 변경

Scala0114 2021. 11. 2. 17:20

1. 액션 추가

from PySide6.QtCore import QObject
from PySide6.QtGui import QIcon, QAction
from PySide6.QtWidgets import QMainWindow, QWidget, QGridLayout

from controller.config_manager import set_geometry, get_geometry
from controller import actions
from widgets.docs_window import DocTab
from widgets.simple import TimeLabel


class MainWindow(QMainWindow, QObject):

        ``` 생략 ```

        # 화주삭제 액션 추가
        delete_owner = QAction(QIcon('src/img/delete_owner_icon.png'), '화주 삭제', self)
        delete_owner.setShortcut('Ctrl+Shift+R')
        delete_owner.setStatusTip('화주 추가')
        delete_owner.triggered.connect(lambda: actions.delete_owner(self, self.central_widget.doc_tab.tab1))
        file_menu.addAction(delete_owner)
        tool_bar.addAction(delete_owner)

        # 화주 이름 변경 액션 추가
        modify_owner = QAction(QIcon('src/img/modify_owner_icon.png'), '화주 이름 변경', self)
        modify_owner.setShortcut('Ctrl+Shift+C')
        modify_owner.setStatusTip('화주 이름 변경')
        modify_owner.triggered.connect(lambda: actions.modify_owner(self, self.central_widget.doc_tab.tab1))
        file_menu.addAction(modify_owner)
        tool_bar.addAction(modify_owner)
        
        
        ``` 생략 ```
  • 화주 삭제(delete_owner), 화주 이름 변경(modify_owner) 액션을 생성하여 메뉴바와 툴바에 추가

  • 각 액션의 triggered 시그널과 controller.actions 의 슬롯함수를 연결

 

 

2. 화주 삭제

# 화주 삭제
def delete_owner(main_window, table_widget, name_data=None):
    # 입력받은 이름이 이미 있는 경우
    if name_data:
        name = name_data

    # 이름을 입력받아야 하는 경우
    else:
        # 다이얼로그 위젯 생성
        delete_owner_dialog = Dialog()
        delete_owner_dialog.setWindowTitle('화주 삭제')
        delete_owner_dialog.setGeometry(500, 500, 300, 50)

        # 화주 이름을 입력받기 위한 다이얼로그 ui 세팅
        grid = QGridLayout()
        input_name = QLineEdit()
        input_name.setPlaceholderText('화주 이름')
        input_name.returnPressed.connect(delete_owner_dialog.success)
        submit = QPushButton('삭제')
        submit.clicked.connect(delete_owner_dialog.success)
        grid.addWidget(QLabel('화주 이름: '), 0, 0, 1, 1)
        grid.addWidget(input_name, 0, 1, 1, 2)
        grid.addWidget(submit, 1, 0, 1, 3)
        delete_owner_dialog.setLayout(grid)

        # 다이얼로그를 modal 하게 표시
        delete_owner_dialog.show_modal()

        # 입력이 취소된경우 (다이얼로그를 그냥 종료한 경우) 삭제절차 종료
        if delete_owner_dialog.canceled:
            return

        # 다이얼로그에서 입력이 완료되면 입력받은 이름을 name 으로 설정
        name = input_name.text()

    # 화주 삭제
    try:
        target = session.query(DayCalOwner).filter(DayCalOwner.name == name).first()
        session.delete(target)
        session.commit()
        table_widget.owner_removed(target.name)
    except UnmappedInstanceError:
        main_window.statusBar().showMessage('>> 등록되지 않은 화주입니다.')
  • 기본적인 흐름은 화주 추가와 동일

  • 쿼리를 통해 입력받은 이름에 해당하는 데이터를 찾아 삭제

  • 삭제를 테이블에 즉각 반영하기 위해 table_widget.owner_removed 실행
  • 해당하는 데이터가 존재하지 않을 경우 status bar에 등록되지 않은 화주임을 표시

 

 

3. 화주 삭제 반영

    # 화주 삭제 반영
    def owner_removed(self, removed_name):
        idx = self.owners.index(removed_name)
        self.input_table.removeColumn(idx)
        del self.owners[idx]
  • 화주 이름 리스트에서 화주의 인덱스를 찾아 해당 인덱스의 열을 삭제하고 화주 이름 리스트에서도 삭제

 

 

4. 화주 이름 변경

# 화주 이름 변경
def modify_owner(main_window, table_widget, name_data=None):
    # 다이얼로그 위젯 생성
    modify_owner_dialog = Dialog()
    modify_owner_dialog.setWindowTitle('화주 이름 변경')
    modify_owner_dialog.setGeometry(500, 500, 300, 50)
    grid = QGridLayout()

    # 화주 이름을 미리 입력받지 않은 경우(메뉴바나 툴바에서 변경액션에 접근한 경우)
    org_name = QLineEdit()
    if not name_data:
        # 화주 이름을 입력받기 위한 다이얼로그 ui 세팅
        org_name.setPlaceholderText('화주 이름')
        grid.addWidget(QLabel('화주 이름: '), 0, 0, 1, 1)
        grid.addWidget(org_name, 0, 1, 1, 2)

    chg_name = QLineEdit()
    chg_name.setPlaceholderText('바꿀 이름')
    chg_name.returnPressed.connect(modify_owner_dialog.success)
    submit = QPushButton('변경')
    submit.clicked.connect(modify_owner_dialog.success)

    grid.addWidget(QLabel('바꿀 이름: '), 1, 0, 1, 1)
    grid.addWidget(chg_name, 1, 1, 1, 2)
    grid.addWidget(submit, 2, 0, 1, 3)
    modify_owner_dialog.setLayout(grid)

    # 다이얼로그를 modal 하게 표시
    modify_owner_dialog.show_modal()

    # 입력이 취소된경우 (다이얼로그를 그냥 종료한 경우) 삭제절차 종료
    if modify_owner_dialog.canceled:
        return

    # 대상 화주이름 name 과 바꿀 이름 changed 를 설정
    name = name_data if name_data else org_name.text()
    changed = chg_name.text()

    # 화주 이름 변경
    try:
        target = session.query(DayCalOwner).filter(DayCalOwner.name == name).first()
        target.name = changed
        session.commit()
        table_widget.owner_modified(name, changed)
    except AttributeError:
        main_window.statusBar().showMessage('>> 등록되지 않은 화주입니다.')
    except DatabaseError:
        main_window.statusBar().showMessage('>> 이미 등록된 화주입니다.')
        session.rollback()
  • Dialog를 통해 변경할 화주의 이름(name)과 바꿀 이름(changed)을 입력받음

  • 데이터베이스에서 name에 해당하는 데이터를 가져와 이름을 변경한 뒤 commit

  • 이름 변경을 즉각 반영하기 위해 table_widget.owner_modified 실행
  • AttributeError 발생시 status bar에 이름을 바꾸려는 화주가 등록되지 않은 화주임을 표시
  • DatabaseError 발생시 status bar에 바꿀 이름이 이미 존재하는 다른 화주의 이름임을 표시

 

 

5. 화주 이름 변경 반영

    # 화주 이름 변경 반영
    def owner_modified(self, org_name, chg_name):
        idx = self.owners.index(org_name)
        self.owners[idx] = chg_name
        self.input_table.setHorizontalHeaderItem(idx, QTableWidgetItem(chg_name))
  • 기존 이름의 인덱스를 찾아 바꿀 이름으로 변경하고 해당 열의 헤더에도 반영

 

 

6. 테스트

 

  • 등록되지 않은 화주 삭제 시도

 

 

 

  • 등록되지 않은 화주의 이름 변경 시도

 

 

 

  • 바꿀 이름이 이미 존재하는 화주의 이름인 경우 

 

 

 

  • 정상적인 삭제

 

 

 

  • 정상적인 이름 변경