이번에는 달력 위젯에서 날짜를 선택하여 해당 날짜의 데이터를 조회하는 기능을 구현한다.
1. DayCalOwnerValues 모델 변경
# 화주별 일일정산 데이터 모델
class DayCalOwnerValues(Base):
__tablename__ = 'daycal_owner_values'
date = Column(Date, primary_key=True)
owner_id = Column(Integer, primary_key=True)
owner_name = Column(String, nullable=False)
owner_type = Column(Integer, nullable=False)
kd_total = Column(Integer, nullable=False)
kd_fare = Column(Integer, nullable=False)
kd_drop = Column(Integer, nullable=False)
kd_fee4 = Column(Integer, nullable=False)
after_deduction = Column(Integer, nullable=False)
match_fee5 = Column(Integer, nullable=False)
owner_fare = Column(Integer, nullable=False)
owner_drop = Column(Integer, nullable=False)
listing_fee4 = Column(Integer, nullable=False)
kd_pre = Column(Integer, nullable=False)
deduction_total = Column(Integer, nullable=False)
total_include_pre = Column(Integer, nullable=False)
def __init__(self, date, owner_id, owner_name, owner_type):
self.date = date
self.owner_id = owner_id
self.owner_name = owner_name
self.owner_type = owner_type
self.kd_total = 0
self.kd_fare = 0
self.kd_drop = 0
self.kd_fee4 = 0
self.after_deduction = 0
self.match_fee5 = 0
self.owner_fare = 0
self.owner_drop = 0
self.listing_fee4 = 0
self.kd_pre = 0
self.deduction_total = 0
self.total_include_pre = 0
def get(self, idx):
if idx == 0:
return self.kd_total
elif idx == 1:
return self.kd_fare
elif idx == 2:
return self.kd_drop
elif idx == 3:
return self.kd_fee4
elif idx == 4:
return self.after_deduction
elif idx == 5:
return self.match_fee5
elif idx == 6:
return self.owner_fare
elif idx == 7:
return self.owner_drop
elif idx == 8:
return self.listing_fee4
elif idx == 9:
return self.kd_pre
elif idx == 10:
return self.deduction_total
elif idx == 11:
return self.total_include_pre
def set(self, idx, val):
if idx == 0:
self.kd_total = val
elif idx == 1:
self.kd_fare = val
elif idx == 2:
self.kd_drop = val
elif idx == 3:
self.kd_fee4 = val
elif idx == 4:
self.after_deduction = val
elif idx == 5:
self.match_fee5 = val
elif idx == 6:
self.owner_fare = val
elif idx == 7:
self.owner_drop = val
elif idx == 8:
self.listing_fee4 = val
elif idx == 9:
self.kd_pre = val
elif idx == 10:
self.deduction_total = val
elif idx == 11:
self.total_include_pre = val
def get_owner_id(self):
return self.owner_id
def get_owner_name(self):
return self.owner_name
def get_owner_type(self):
return self.owner_type
- 예전 데이터를 가져올 경우 지금은 삭제된 화주가 그 당시 데이터에는 존재할 수도 있기 때문에
화주 리스트를 DayCalOwnerValues 리스트를 토대로 임시로 생성해야한다. - 그러기 위해서는 DayCalOwner 객체의 정보가 DayCalOwnerValues 에도 존재해야하기 때문에
DayCalOwnerValues 모델에 owner_type 필드를 추가하고 생성자도 수정해준다. - 물론 해당 모델의 인스턴스를 생성하는 메소드에서도 모두 매개변수로 화주 타입을 넘겨주도록 수정한다.
2. TimeLabel 위젯 수정
# 시간레이블 클래스(QLabel 상속)
# 1초마다 현재 날짜/시간을 갱신하여 표시하는 레이블
class TimeLabel(QLabel):
clicked = Signal()
def __init__(self):
super().__init__()
self.timer = QTimer(self)
self.timer.timeout.connect(self.timeout)
self.timer.start(100)
self.init_ui()
def init_ui(self):
self.setText(QDateTime.currentDateTime().toString('yyyy년 MM월 dd일 ddd hh:mm:ss'))
def timeout(self):
self.setText(QDateTime.currentDateTime().toString('yyyy년 MM월 dd일 ddd hh:mm:ss'))
def mouseReleaseEvent(self, ev: QMouseEvent) -> None:
self.clicked.emit()
- 상태표시줄에 표시된 날짜/시간 부분을 클릭하면 데이터를 조회할 날짜를 선택하기 위한 달력 위젯이 표시되도록
하기 위해 먼저 TimeLabel의 mouseReleaseEvent 를 오버라이드하여 clicked 시그널을 구현해준다.
3. MainWindow 수정
# 시간 레이블 추가
time_label = TimeLabel()
time_label.clicked.connect(lambda: actions.date_query(self, self.central_widget.get_selected_tab()))
status_bar.addPermanentWidget(time_label)
- MainWindow의 time_label을 상태표시줄에 추가하는 부분에서 time_label의 clicked 시그널에 date_query를
호출하는 람다함수를 연결해준다. 이 때, central_widget의 get_selected_tab 을 호출하여 현재 선택된 탭 정보를
받아와 매개변수로 넘겨준다.
4. CentralWidget 수정
# 중앙 위젯
class CentralWidget(QWidget):
def __init__(self, parent):
super().__init__(parent)
self.doc_tab = DocTab()
self.doc_tab.setParent(self)
self.init_ui()
def init_ui(self):
self.setStyleSheet("background-color: #FFFFFF")
# 그리드 레이아웃
grid = QGridLayout()
# 탭 위젯 추가
grid.addWidget(self.doc_tab, 0, 0)
# 중앙 위젯에 그리드 레이아웃 적용
self.setLayout(grid)
def get_selected_tab(self):
cur = self.doc_tab.currentWidget()
return 0 if cur == self.doc_tab.tab1 else 1 if self.doc_tab.tab2 else 2
- CentralWidget에 선택된 탭이 몇번 탭인지 반환하는 get_selected_tab 메소드를 구현한다
- tab1이라면 0, tab2라면 1, tab3라면 2를 반환한다.
5. date_query 함수 작성
# 날짜로 데이터 조회
def date_query(parent, tab):
date_select = DateSelect(parent)
date_select.show_modal()
if not date_select.canceled:
if tab == 0:
today = date_select.calendar.selectedDate().toString('yyyy-MM-dd')
result = DayCalQueryResult(parent, get_daycal_owner_values(today), get_daycal_other_values(today), get_daycal_result(today), today)
result.show()
- 호출시에 매개변수로 전달받은 parent 를 부모 위젯으로 하여 DataSelect 다이얼로그를 생성, modal하게 표시한다
=> DataSelect 는 달력 위젯을 사용하여 유저가 선택한 날짜를 가져오기 위한 위젯이다. - DataSelect 다이얼로그가 정상적으로 제출되었을 경우 받아온 날짜를 기준으로 DayCalOwnerValues,
DayCalOtherValues, DayCalResult 정보를 DB에서 읽어온다. - 읽어온 정보를 기반으로 DayCalQueryResult 위젯을 생성하여 표시한다.
=> DayCalQueryResult 는 조회된 데이터를 테이블로 나타내주기 위한 위젯이다.
6. DataSelect 다이얼로그 구현
# 날짜로 데이터 조회를 위한 달력 위젯
# 다이얼로그(QDialog 상속)
class DateSelect(QDialog):
def __init__(self, parent):
super().__init__(parent)
self.calendar = QCalendarWidget()
self.submit = QPushButton('조회')
self.submit.clicked.connect(self.success)
self.canceled = True
self.init_ui()
def init_ui(self):
grid = QGridLayout()
grid.addWidget(self.calendar, 0, 0, 1, 3)
grid.addWidget(self.submit, 1, 0, 1, 1)
self.setLayout(grid)
def show_modal(self):
return super().exec_()
def success(self):
self.canceled = False
self.close()
- QDialog 를 상속하여 구현
- 날짜선택을 위한 달력(QCalendarWidget)과 선택된 날짜정보를 제출하기 위한 버튼(QPushButton)을 가진 위젯.
7. DayCalQueryResult 구현
# 날짜로 조회한 데이터를 표시하기 위한 위젯
# 기본적으로 DayCal 위젯과 거의 동일한 구조를 가짐
class DayCalQueryResult(QDialog):
# 생성자
def __init__(self, parent, owner_values, other_values, result, today):
super().__init__(parent)
# 화주별 데이터, 기타 데이터, 결과 데이터, 조회날짜를 인자로 받아온다
self.owner_values = owner_values
self.other_values = other_values
self.result = result
self.today = today
# 화주별 데이터를 기반으로 임시 화주 명단을 생성
self.owner_list = []
for values in self.owner_values:
self.owner_list.append(DayCalOwner(values.get_owner_name(), values.get_owner_type(), values.get_owner_id()))
# 입력 테이블 생성(화주별 데이터)
self.input_table = TableView()
self.data_model = DayCalTableModel(self, self.owner_list, self.owner_values)
self.input_table.setModel(self.data_model)
# 기타 테이블 생성(기타 데이터)
self.other_table = TableView()
self.other_data_model = DayCalOthersTableModel(self, self.other_values)
self.other_table.setModel(self.other_data_model)
# 결과 테이블 생성
self.result_table = TableView()
self.result_data_model = DayCalResultTableModel(self, self.result)
self.result_table.setModel(self.result_data_model)
self.init_ui()
# ui 초기화
def init_ui(self):
# 그리드 레이아웃
grid = QGridLayout()
# 테이블위젯 추가
grid.addWidget(self.input_table, 0, 0)
grid.addWidget(self.other_table, 1, 0)
grid.addWidget(self.result_table, 0, 1, 2, 1)
grid.setRowStretch(0, 5)
grid.setColumnStretch(0, 5)
# 레이아웃 세팅
self.setLayout(grid)
# 초기 윈도우사이즈 설정
self.setGeometry(100, 100, 1446, 620)
# 스타일 설정
self.setStyleSheet("background-color: #FFFFFF")
# 타이틀 설정
self.setWindowTitle("일일정산서 계산서: " + self.today)
- 날짜로 조회한 데이터를 테이블의 형태로 표시해주기 위한 위젯
- 기본적으로 DayCal 위젯과 거의 동일한 구조를 가진다.
- 다른 점이라면 과거의 데이터를 가져오는 것이기 때문에 화주를 추가/삭제할 일이 없으며
이미 삭제된 화주나 추가된 화주는 여기에 영향을 미치지 않는다 - 테이블 모델에서 필요로하는 owner_list는 owner_values를 기반으로 임시로 생성한다.

전날의 데이터를 조회하면 테이블 형태로 어제의 데이터가 표시되는 것을 볼 수 있다.
화주2는 오늘 추가되었기 때문에 전날의 데이터에는 나타나지 않는다.
'개인 프로젝트 > Accounting Program' 카테고리의 다른 글
#21 디자인 변경 (0) | 2021.12.20 |
---|---|
#20 데이터 조회 - 수정기능 구현 (0) | 2021.12.07 |
#18 저장기능 구현 (0) | 2021.11.25 |
#17 QTableView (0) | 2021.11.22 |
#16 화주 삭제, 화주 이름 변경 (0) | 2021.11.02 |