1. DayCalOwner 모델 변경
# 화주 모델
class DayCalOwner(Base):
__tablename__ = 'daycal_owner'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, unique=True)
def __init__(self, name):
self.name = name
- autoincrement 가 설정된 id 속성을 추가
- primary key를 name에서 id로 변경
- name을 primaryk 중복 불가능한 값으로 하기 위해 unique 설정
2. actions.py
from PySide6.QtWidgets import QLabel, QGridLayout, QPushButton, QLineEdit
from sqlalchemy.exc import DatabaseError
from sqlalchemy.orm.exc import UnmappedInstanceError
from controller.db_manager import session
from models.models import DayCalOwner
from widgets.simple import Dialog
# 화주 추가
def create_owner(main_window, table_widget, name_data=None):
# 입력받은 이름이 이미 있는 경우
if name_data:
name = name_data
# 이름을 입력받아야 하는 경우
else:
# 다이얼로그 위젯 생성
create_owner_dialog = Dialog()
create_owner_dialog.setWindowTitle('화주 추가')
create_owner_dialog.setGeometry(500, 500, 300, 50)
# 화주 이름을 입력받기 위한 다이얼로그 ui 세팅
grid = QGridLayout()
input_name = QLineEdit()
input_name.setPlaceholderText('화주 이름')
input_name.returnPressed.connect(create_owner_dialog.success)
submit = QPushButton('추가')
submit.clicked.connect(create_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)
create_owner_dialog.setLayout(grid)
# 다이얼로그를 modal 하게 표시
create_owner_dialog.show_modal()
# 입력이 취소된경우 (다이얼로그를 그냥 종료한 경우) 추가절차 종료
if create_owner_dialog.canceled:
return
# 다이얼로그에서 입력이 완료되면 입력받은 이름을 name 으로 설정
name = input_name.text()
# 새 화주 추가
new_owner = DayCalOwner(name)
try:
session.add(new_owner)
session.commit()
table_widget.owner_added(name)
except DatabaseError:
main_window.statusBar().showMessage('>> 이미 등록된 화주입니다.')
session.rollback()
- main_window 에 구현했던 화주 추가 액션을 controller 디렉토리의 actions.py 로 이동
- self 대신 메인윈도우의 인스턴스와 화주 추가 결과를 반영할 table이 위치한 위젯의 인스턴스를 인자로 받음
- dialog를 통하지않고 이름을 입력받을 상황을 대비하여 name_data 인자를 추가
- name_data가 입력되었다면 다이얼로그로 이름을 입력받지 않고 name_data를 name으로 설정
- 중복된 이름일 경우 status bar에 이미 등록된 화주임을 표시
- name이 더이상 primary key가 아닌 unique key이기 때문에 이름이 중복될 경우 add 가 아닌 commit단계에서
예외가 발생한다. 그러므로 예외 발생시 이미 적용된 add 를 취소하기 위해 rollback을 호출해줘야한다.
from controller import actions
``` 생략 ```
# 화주추가 액션 추가
create_owner = QAction(QIcon('src/img/create_owner_icon.png'), '화주 추가', self)
create_owner.setShortcut('Ctrl+Shift+A')
create_owner.setStatusTip('화주 추가')
create_owner.triggered.connect(lambda: actions.create_owner(self, self.central_widget.doc_tab.tab1))
file_menu.addAction(create_owner)
tool_bar.addAction(create_owner)
``` 생략 ```
- contoller.actions를 import 한 뒤 create_owner 액션의 triggered 시그널에 lambda 함수의 형태로 연결해준다.
3. simple.py
from PySide6.QtCore import QDateTime, QTimer
from PySide6.QtWidgets import QLabel, QDialog
# 시간레이블 클래스(QLabel 상속)
# 1초마다 현재 날짜/시간을 갱신하여 표시하는 레이블
class TimeLabel(QLabel):
def __init__(self):
super().__init__()
self.setText(QDateTime.currentDateTime().toString('yyyy년 MM월 dd일 ddd hh:mm:ss'))
self.timer = QTimer(self)
self.timer.timeout.connect(self.timeout)
self.timer.start(100)
def timeout(self):
self.setText(QDateTime.currentDateTime().toString('yyyy년 MM월 dd일 ddd hh:mm:ss'))
# 다이얼로그(QDialog 상속)
class Dialog(QDialog):
def __init__(self):
super().__init__()
self.canceled = True
def show_modal(self):
return super().exec_()
def success(self):
self.canceled = False
self.close()
- Dialog, TimeLabel 등의 구조가 간단한 위젯들을 widgets/simple.py 에 분리
4. DayCal 위젯
# 일일 정산서 계산서 위젯
class DayCal(QWidget):
# 생성자
def __init__(self):
super().__init__()
self.owners = [q.name for q in session.query(DayCalOwner).order_by(DayCalOwner.id)]
self.num_of_owners = len(self.owners)
self.input_table = QTableWidget()
self.input_table.setParent(self)
self.init_ui()
``` 생략 ```
- 화주 데이터의 id를 기반으로 순서를 유지하도록 쿼리시에 order_by 를 통해 id를 기준으로 오름차순 정렬
5. create_owner 수정
# 화주 추가
def create_owner(main_window, table_widget, name_data=None):
# 입력받은 이름이 이미 있는 경우
if name_data:
name = name_data
# 이름을 입력받아야 하는 경우
else:
# 다이얼로그 위젯 생성
create_owner_dialog = Dialog()
create_owner_dialog.setWindowTitle('화주 추가')
create_owner_dialog.setGeometry(500, 500, 300, 50)
# 화주 이름을 입력받기 위한 다이얼로그 ui 세팅
grid = QGridLayout()
input_name = QLineEdit()
input_name.setPlaceholderText('화주 이름')
input_name.returnPressed.connect(create_owner_dialog.success)
submit = QPushButton('추가')
submit.clicked.connect(create_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)
create_owner_dialog.setLayout(grid)
# 다이얼로그를 modal 하게 표시
create_owner_dialog.show_modal()
# 입력이 취소된경우 (다이얼로그를 그냥 종료한 경우) 추가절차 종료
if create_owner_dialog.canceled:
return
# 다이얼로그에서 입력이 완료되면 입력받은 이름을 name 으로 설정
name = input_name.text()
# 새 화주 추가
new_owner = DayCalOwner(name)
try:
session.add(new_owner)
session.commit()
table_widget.owner_added(name)
except DatabaseError:
main_window.statusBar().showMessage('>> 이미 등록된 화주입니다.')
session.rollback()
- 이름을 입력하기 위한 위젯을 QPlainText 에서 QLineEdit 으로 변경
- returnPressed 시그널을 사용하여 엔터키에도 반응하도록 수정
- 다이얼로그에 canceled 속성을 추가하여 단순 종료와 데이터를 정상적으로 제출한 종료를 구분
- 데이터를 정상적으로 제출했을 때만 기능이 동작하도록 수정
'개인 프로젝트 > Accounting Program' 카테고리의 다른 글
#17 QTableView (0) | 2021.11.22 |
---|---|
#16 화주 삭제, 화주 이름 변경 (0) | 2021.11.02 |
#14 화주 추가 (0) | 2021.11.01 |
#13 데이터베이스 연결 (0) | 2021.10.30 |
#12 메인 화면 구성 (0) | 2021.10.28 |