이번에는 달력 위젯에서 날짜를 선택하여 해당 날짜의 데이터를 조회하는 기능을 구현한다. 

 

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

+ Recent posts