언어/Python

Qt Designer 사용법 발표 및 로또 번호 추첨기 [2023-05-08 학습일지]

플광 2023. 5. 30. 08:52

 

주말동안 열심히 공부하면서 교육자료를 짧게 만들어보았다.

 

감사하게도 요약한 내용에 대해 발표할 기회를 주셔서, 짧게 1시간 정도 발표할 수 있었습니다.

 

많은 분들이 집중하여 들어주셔서 큰 용기가 되었습니다.

 

How to use Qt Designer.pdf
2.50MB

 

오늘의 과제로 로또 번호 추첨기를 만들었다.

 

6개가 되면 some_widget.setEnabled(False)를 줘서 추가로 선택하지 못하게 기능을 추가해보았습니다.

 

소스코드는 다음과 같습니다.

"""
    fileName : MyLottoLogic.py
    description : 로또 추출기 클래스
"""

import random


class LottoNumExtractor():
    def __init__(self):
        self.to_check_list = []
        self.this_time_extraction_numbers = []

    def __repr__(self):
        return f"now check_list = {self.to_check_list} and now extracted num = {self.this_time_extraction_numbers}"

    def make_new_lotto_num(self):
        self.this_time_extraction_numbers = random.sample([x for x in range(1, 46)], 7)

    def get_extracted_lotto_num(self):
        return self.this_time_extraction_numbers

    def get_lotto_result(self, list_):
        if len(list_) != 6:
            raise "6개 숫자가 들어와야 합니다"
        for n in list_:
            if not 0 <= n <= 45:
                raise f"1~45의 숫자가 들어와야합니다. 문제가 되는 입력 : {n}"

        self.make_new_lotto_num()
        count = 0
        for n in list_:
            if n in self.this_time_extraction_numbers[:6]:
                count += 1

        if count == 6:  # 1등인 경우
            return 1
        elif count == 5:  # 2, 3등인 경우
            if self.this_time_extraction_numbers[6] in list_:
                return 2
            else:
                return 3

        elif count == 4:  # 4등인 경우
            return 4
        elif count == 3:  # 5등인 경우
            return 5

        return 6


if __name__ == '__main__':
    app = LottoNumExtractor()
    for i in range(100):
        print(app.get_lotto_result([1, 2, 3, 4, 5, 6]))
"""
    fileName : lotto_window.py
    description : 로또 번호 고르고, 당첨결과를 조회하는 GUI 화면 클래스
"""

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import SelectionLottoWindow
import MyLottoLogic


class MyLottoWindow(QMainWindow, SelectionLottoWindow.Ui_LottoWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self) # desinger 디자인대로 셋업
        self.make_widget_groups() # 위젯(combobox, checkbox, pushbutton) 그룹을 만들어줌
        self.make_lotto_machine() # 로또 번호 생성하고, 6자리 리스트를 넣으면 당첨결과를 반환하는 객체를 만듦
        self.make_my_lucky_num_list() # 각 라인별로 선택한 번호를 저장할 리스트를 생성함

        #### 시그널 선언 ####
        self.connect_signal_comboboxs() # 콤보박스 시그널 매칭
        self.connect_signal_checkboxs() # 체크박스 시그널 매칭
        self.connect_signal_pushbuttons() # 푸시버튼 시그널 매칭

        # "당첨결과 확인하기" 눌렀을 경우
        self.get_lotto_btn_1.clicked.connect(lambda x: self.check_lotto_result(1)) # 1번 라인 당첨 결과 확인
        self.get_lotto_btn_2.clicked.connect(lambda x: self.check_lotto_result(2)) # 2번 라인 당첨 결과 확인
        self.get_lotto_btn_3.clicked.connect(lambda x: self.check_lotto_result(3)) # 3번 라인 당첨 결과 확인
        # TODO: <기능> <통계> 버튼 눌렀을 경우, 메시지창 띄우기

    # TODO: lineEdit_1 중복 있을 시, result_label_1 에 중복값 있다고 setText
    def make_my_lucky_num_list(self):
        self.my_lucky_num_list_1 = [1, 2, 3, 4, 5, 6]
        self.my_lucky_num_list_2 = []
        self.my_lucky_num_list_3 = []

    def make_lotto_machine(self):
        self.lotto_machine = MyLottoLogic.Lotto_Num_Extractor()

    def make_widget_groups(self):
        ### 변수 그룹 선언 ###
        self.combo_group = []  # combobox
        self.cb_group = []  # checkbox
        self.pb_group = []  # pushbutton
        for i in range(1, 7):
            self.combo_group.append(self.__getattribute__("combo_" + f"{i}"))

        for i in range(1, 46):
            self.cb_group.append(self.__getattribute__("cb_" + f"{i:02}"))

        for i in range(1, 46):
            self.pb_group.append(self.__getattribute__("pb_" + f"{i:02}"))

    def connect_signal_comboboxs(self):
        for i, combobox in enumerate(self.combo_group):
            combobox.currentIndexChanged.connect(lambda x, y=i: self.add_my_lucky_num_list_1(x, y))

    def connect_signal_checkboxs(self):
        for i, checkbox in enumerate(self.cb_group):
            checkbox.toggled.connect(lambda x, y=i: self.add_my_lucky_num_list_2(x, y + 1))

    def connect_signal_pushbuttons(self):
        for i, pushbutton in enumerate(self.pb_group):
            pushbutton.toggled.connect(lambda x, y=i: self.add_my_lucky_num_list_3(x, y + 1))

    def console_print_group_state(self):
        """
        콘솔에 group 찍기
        :return: None
        """
        print('combo_group')
        for i in self.combo_group:
            print(i.objectName())

        print('checkbox_group')
        for i in self.cb_group:
            print(i.objectName())

        print('pushbutton_group')
        for i in self.pb_group:
            print(i.objectName())

    def check_lotto_result(self, btn_index):
        """
        "당첨결과 확인하기" 눌렀을 경우 , 해당 my_lucky_num_list 의 선택번호대로 당첨결과를 메세지박스로 알려줌
        :param btn_index:
        :return: None
        """
        if btn_index == 1:
            result = self.lotto_machine.get_lotto_result(self.my_lucky_num_list_1)
        elif btn_index == 2:
            result = self.lotto_machine.get_lotto_result(self.my_lucky_num_list_2)
        elif btn_index == 3:
            result = self.lotto_machine.get_lotto_result(self.my_lucky_num_list_3)

        if result == 6:
            result = "낙첨"
        else:
            result = str(result) + "등"
        QMessageBox.about(self, "당첨 결과",
                          f"""추첨번호 : {sorted(self.lotto_machine.get_extracted_lotto_num()[:6])}, 보너스 번호 : {self.lotto_machine.get_extracted_lotto_num()[6]} 
    선택 번호 : {sorted(self.__getattribute__(f"my_lucky_num_list_{btn_index}"))}\n당첨 결과는 {result} 입니다.""")

    def add_my_lucky_num_list_1(self, num, list_index):
        """
        combobox의 값을 설정할 때 마다, my_lucky_num_list_1 에 값을 변경 하는 함수
        :param num: 콤보 박스에서 선택한 값
        :param list_index: 몇 번째 콤보박스에서 값을 던지는지 인덱스를 받음
        :return:
        """

        self.my_lucky_num_list_1.pop(list_index)
        self.my_lucky_num_list_1.insert(list_index, num + 1)
        print(self.my_lucky_num_list_1)
        self.show_my_lucky_num_list(1)

    def add_my_lucky_num_list_2(self, toggle_value, num):
        if toggle_value is True:
            self.my_lucky_num_list_2.append(num)
        else:
            self.my_lucky_num_list_2.remove(num)

        if len(self.my_lucky_num_list_2) < 6:
            for i, checkbox in enumerate(self.cb_group):
                checkbox.setEnabled(True)
        else:
            for i, checkbox in enumerate(self.cb_group):
                if (i + 1) not in self.my_lucky_num_list_2:
                    checkbox.setEnabled(False)
        self.show_my_lucky_num_list(2)

    def add_my_lucky_num_list_3(self, toggle_value, num):
        if toggle_value is True:
            self.my_lucky_num_list_3.append(num)
        else:
            self.my_lucky_num_list_3.remove(num)

        if len(self.my_lucky_num_list_3) < 6:
            for i, checkbox in enumerate(self.pb_group):
                checkbox.setEnabled(True)
        else:
            for i, checkbox in enumerate(self.pb_group):
                if (i + 1) not in self.my_lucky_num_list_3:
                    checkbox.setEnabled(False)
        self.show_my_lucky_num_list(3)

    def show_my_lucky_num_list(self, index):
        """
        my_lucky_num_list_1에 따라 label 표시 함수
        :return: None
        """
        sorted_string_list = []

        for i in sorted(self.__getattribute__(f"my_lucky_num_list_{index}")):
            if i != 0:
                sorted_string_list.append(str(i))

        result_string = ", ".join(sorted_string_list)

        self.__getattribute__("result_label_" + str(index)).setText(result_string)

    def list_has_no_repeat(self, list_):
        """
            로또 번호는 중복값이 없음. 뽑은 숫자 리스트를 인자로 받음
            중복값이 있을 경우 False를
            중복값이 없을 경우 True를 반환한다.
        :return: boolean
        """
        list_set = set(list_)
        if len(list_set) != len(list_):
            return False
        else:
            return True


if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWindow = MyLottoWindow()
    myWindow.show()
    app.exec_()​

 

 

 

 

감사합니다.