ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • KMS12 : Python PyQt5를 이용한 줌 반자동 참가기 (source)
    Program_Light 2021. 7. 3. 13:00

    KMS12 - Zoom auto Join

     지난번 만든 줌 반자동 참가기를 업그레이드 시켜 최종적으로 완성시켰습니다.

    이전에 만든 줌 반자동 참가기

     

    줌 반자동 참가기를 배포하고, 실제로 사용해보면서, 불편한 점들을 몇 가지 느꼈습니다. 우선, 그 날의 전체 시간표를 알 수 없다는 것입니다. UI는 간편할수록 좋다는 원칙에 따라서, 기존 줌 반자동 참가기는 그 시간대의 추천 과목만을 보여주었습니다. 즉, 그 날의 시간표는 알지 못했습니다. 실사용을 해보니, 이 부분은 상당히 불편한 부분이여서, 새 버전에는 그 날의 시간표또한 띄어지도록 만들었습니다.
     두 번째로는, UI가 단색조라는 것입니다. 그래도 사용자가 사용하는 프로그램인 이상, UI에 신경을 쓰지 않을 수는 없었습니다. 과거 흑백의 UI를 가진 프로그램은 상당히 날것의 프로그램 느낌을 주어서, 새 버전에는 동탄 중앙고의 로고에 영감을 딴 파란 계열의 디자인을 UI에 적용시켜보았습니다.
     마지막으로, 버그가 있다는 것입니다. 그다지 치명적인 버그는 아니지만, 주말에 프로그램 실행이 되지 않는 오류, 몇 가지 특정한 조작을 하면 줌 참가가 불가능해지는 버그(재시작해면 해결됐었음) 가 있었습니다. 새 버전에는 모두 고쳤습니다.


    <소스>

    source,py (줌 초대 URL은 모두 정보 보호를 위해 바꾸었습니다)

    import datetime
    import sys
    import time
    import webbrowser
    import PyQt5
    
    from PyQt5.QtWidgets import QApplication, QMainWindow, QAction, qApp, QLabel, QComboBox, QPushButton, QMessageBox
    from PyQt5.QtGui import QIcon, QPainter, QPen, QColor
    
    cnt = -1
    rec = -1
    roomNo = -1
    subName = ["담임 조종례", "국어", "수학", "영어", "통합사회", "통합과학", "과학탐구", "기술가정", "미술", "한국사", "체육", "진로", "담임창체", "동아리"]
    subURL = ["담임조종례 줌 참가 링크",
              "국어 줌 참가 링크",
              "수학 줌 참가 링크",
              "영어 줌 참가 링크",
              "통합사회 줌 참가 링크",
              "통합과학 줌 참가 링크",
              "과학탐구 줌 참가 링크",
              "기술가정 줌 참가 링크",
              "미술 줌 참가 링크",
              "한국사 줌 참가 링크",
              "체육 줌 참가 링크",
              "진로 줌 참가 링크",
              "담임창체 줌 참가 링크",
              "동아리 줌 참가 링크"
              ]
    subTimeTable = [
        [0, 2, 4, 9, 3, 10, 1, 5],
        [0, 3, 2, 4, 9, 1, 7, 11],
        [0, 5, 7, 1, 2, 3, 6, 0],
        [0, 1, 8, 8, 7, 4, 2, 9],
        [0, 5, 3, 10, 8, 12, 13, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
    ]
    
    def logicA(a, num, b):
        if((a <= num) and (num <= b)):
            return 1
        else:
            return 0
    
    def calcSubTime(dayT, hour, minute):
        if(dayT >= 5):
            return -1
    
        num = hour * 100 + minute #hour의 십진법 표기. 60진법이 더 효율적임
        if(hour <= 7):
            return -1
        elif(logicA(800, num, 856)):
            return 0
        elif(logicA(857, num, 954)): # 910 ~ 1000
            return 1
        elif(logicA(955, num, 1054)): # 1010 ~ 1100
            return 2
        elif(logicA(1055, num, 1154)): # 1110 ~ 1200
            return 3
        elif(logicA(1155, num, 1314)): # 1210 ~ 1300
            return 4
        elif(logicA(1315, num, 1329)): # 1300 ~ 1400
            return -1
        elif(logicA(1330, num, 1444)): # 1400 ~ 1450
            return 5
        elif(logicA(1445, num, 1544)): # 1500 ~ 1550
            return 6
        else:
            if((dayT == 2) or (dayT == 4)):
                if(logicA(1545, num, 1609)):
                    return 0
                else:
                    return -1
            else:
                if(logicA(1545, num, 1644)): # 1600 ~ 1650
                    return 7
                elif(logicA(1645, num, 1709)):
                    return 0
                else:
                    return -1
    
    class MyApp(QMainWindow):
    
        def __init__(self):
            super().__init__()
            self.initUI()
    
        def initUI(self):
            global cnt
            cnt = 0
    
            # manu bar
            exitAction = QAction(QIcon('logo.png'), 'Exit', self)
            exitAction.setShortcut('Ctrl+Shift+E')
            exitAction.setStatusTip('Exit application')
            exitAction.triggered.connect(qApp.quit)
    
            joinAction = QAction(QIcon('logo.png'), 'Join', self)
            joinAction.setShortcut('Ctrl+J')
            joinAction.setStatusTip('Join selected subject')
            joinAction.triggered.connect(self.onClicked)
    
            self.statusBar()
    
            menubar = self.menuBar()
            menubar.setNativeMenuBar(False)
            filemenu = menubar.addMenu('&Cmd')
            filemenu.addAction(exitAction)
            filemenu.addAction(joinAction)
    
            #subject table lable
            self.tabLbl = QLabel('lable for subject table', self)
            self.tabLbl.move(410, 50)
            self.tabLbl.resize(100, 200)
            self.tabLbl.setStyleSheet("color: #002255;")
    
            font1 = self.tabLbl.font()
            font1.setPointSize(10)
            font1.setBold(True)
            self.tabLbl.setFont(font1)
            self.tabLbl.adjustSize()
    
            #subject recommand lable
            self.lbl = QLabel('lable for reccommanding subject', self)
            self.lbl.move(100, 225)
            self.lbl.resize(200, 40)
    
            font1 = self.lbl.font()
            font1.setPointSize(12)
            font1.setBold(True)
            self.lbl.setFont(font1)
    
            self.lbl.adjustSize()
    
            # select combo box
            cb = QComboBox(self)
            cb.setEditable(True)
            for i in subName:
                cb.addItem(i)
            #cb.setStyleSheet("QComboBox" "{" "background-color: #A6C4F1;" "}")
            cb.setStyleSheet("QComboBox" "{" "background-color: #EEEEFF;" "}")
            cb.activated[str].connect(self.onActivated)
            cb.resize(200, 30)
            cb.move(100, 90)
    
            # join button
            bt1 = QPushButton("선택된\n과목", self)
            bt1.clicked.connect(self.onClicked)
            #bt1.setStyleSheet("background-color: #B6D4FF")
            bt1.setStyleSheet("background-color: #EEEEFF")
            bt1.resize(75, 60)
            bt1.move(125, 135)
    
            #autojoin button
            bt2 = QPushButton("현재 시각의\n추천과목", self)
            bt2.clicked.connect(self.onClicked2)
            #bt2.setStyleSheet("background-color: #B6D4FF")
            bt2.setStyleSheet("background-color: #EEEEFF")
            bt2.resize(75, 60)
            bt2.move(200, 135)
    
            #refresh button
            bt3 = QPushButton("추천 과목 새로고침", self)
            bt3.clicked.connect(self.refreshSub)
            bt3.move(5, 25)
    
            #bt3.setStyleSheet("background-color: #AFAFAF")
            bt3.setStyleSheet("background-color: #A0B4E6")
            font1 = bt3.font()
            font1.setPointSize(8)
            bt3.setFont(font1)
            bt3.adjustSize()
    
            self.refreshSub()
    
            #Activate
            self.setWindowIcon(QIcon('logo.png'))
            self.setWindowTitle('Che Jang ill ban')
            self.setGeometry(300, 300, 480, 295)
            self.show()
    
        def paintEvent(self, e):
            qp = QPainter()
            qp.begin(self)
            self.draw_pr(qp)
            qp.end()
    
        #draw rectangle to subject table layout
        def draw_pr(self, qp):
            #background
            qp.setBrush(QColor(255, 255, 255))
            qp.setPen(QPen(QColor(255, 255, 255), 1))
            qp.drawRect(0, 50, 400, 270)
    
            #vertical
            qp.setBrush(QColor(125, 170, 210))
            qp.setPen(QPen(QColor(125, 170, 210), 1))
            qp.drawRect(400, 50, 80, 270)
    
            #horizontal
            qp.setBrush(QColor(180, 200, 230))
            qp.setPen(QPen(QColor(180, 200, 230), 1))
            qp.drawRect(0, 0, 400, 50)
    
            #point
            qp.setBrush(QColor(100, 150, 200))
            qp.setPen(QPen(QColor(100, 150, 200), 1))
            qp.drawRect(400, 0, 80, 50)
    
        def onActivated(self, text):
            global cnt
            cnt = 0
            for i in subName:
                if text == i:
                    break
                cnt += 1
    
            print('combobox selected : ' + str(cnt) + 'th subject')
    
        # 현재 선택한 과목의 줌으로 접속
        def onClicked(self):
            global cnt, roomNo
            roomNo = cnt
            self.joinRoom()
    
        # 현재 시간의 추천 과목으로 접속
        def onClicked2(self):
            global rec, roomNo
            self.refreshSub()
            roomNo = rec
            self.joinRoom()
    
        def joinRoom(self):
            global roomNo
            print("join button was clicked")
            if (roomNo == 13):
                # reply = QMessageBox.question(self, '주의!', '동아리는 프로그램 구조상 JA code 동아리의\nzoom room에 들어가도록 설계되었습니다.\n진행하시겠습니까?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                QMessageBox.question(self, '주의!',
                                             '동아리는 구조상 모든 학생들의 room이 다르므로 \n단일 프로그램으로는 구현할 수 없는 기능입니다.\n자세한 내용은 개발자에게 문의하십시오',
                                             QMessageBox.Ok, QMessageBox.Ok)
            elif (roomNo != -1):
                reply = QMessageBox.question(self, '안내', subName[roomNo] + ' 줌 교실에 참가합니다',
                                             QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
                if reply == QMessageBox.No:
                    return
                print("push webbrowser open command")
                webbrowser.open(subURL[roomNo])
            else:
                QMessageBox.question(self, '안내', '현재 추천과목이 없습니다.',
                                     QMessageBox.Ok, QMessageBox.Ok)
    
        def refreshSub(self):
            global rec
            dayT = datetime.datetime.today().weekday()
            now = time.localtime()
            hour = now.tm_hour
            minute = now.tm_min
            T = calcSubTime(dayT, hour, minute)
            print('refresh / ' + str(T) + ' class of ' + str(dayT + 1) + 'th day : ' + subName[subTimeTable[dayT][T]])
    
            #recommend subject
            if(T == -1):
                rec = -1
            else:
                rec = subTimeTable[dayT][T]
            if(T == -1):
                self.lbl.setText('추천 과목: NONE')
            else:
                self.lbl.setText('추천 과목 : (' + str(T) + ' 교시) ' + subName[subTimeTable[dayT][T]])
            self.lbl.adjustSize()
            self.lbl.move(200 - int(self.lbl.size().width() / 2), 225)
    
            #recommend subject table
            self.tabLbl.setText("\n")
            if (dayT <= 4):
                for i in range(1, 7 if ((dayT == 2) or (dayT == 4)) else 8):
                    self.tabLbl.setText(self.tabLbl.text() + subName[subTimeTable[dayT][i]] + "\n\n")
            self.tabLbl.adjustSize()
    
            self.statusBar().showMessage('updated at ' + str(now.tm_hour) + 'h ' + str(now.tm_min) + 'min ' + str(now.tm_sec) + 'sec')
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = MyApp()
        sys.exit(app.exec_())
    
    

    <실행파일>

    사실상 이 글에서 줌 URL을 일시적으로 다른 문자열로 바꾸어놓았고, 애초에 사람들마다 시간표, 선생님 줌 초대 링크마다 소스코드에서 상수로 사용하는 값이 달라지므로 실행파일을 올려드리는건 의미가 없다 생각했습니다.

     

    그래서, 자신에게 맞춰 수정한 파이썬 파일을 .exe파일로 변경할 수 있는 방법을 알 수 있는 사이트를 알려드리겠습니다

    https://wikidocs.net/21952

     

    위키독스

    온라인 책을 제작 공유하는 플랫폼 서비스

    wikidocs.net

    + 참고 : 실행화면

    이상으로 KMS 였습니다. 감사합니다.

하면된다 學業報國