AUTO TRADE/[대신증권] CYBOS PLUS

대신증권 CYBOS PLUS 프로그램 구현 (3) - GUI와 연결하기

프로그램 구현 목표

  • PyQt5 Qt Designer를 통해 코드와 연결하기
  • 버튼 하나 동작해보기

지난 게시글까지는 로그인을 자동적으로 처리하는 방법에 대해 살펴보았고, 로그인 기능 자체도 정상적으로 동작하고 있음을 잘 확인하고 넘어왔다. 사실 여태까지 언급하지는 않았지만 우리가 제작했던 코드는 기본적으로 코드를 실행시킨 이후, 우리가 동작시키고자 하는 코드가 모두 돌아간 후에 Process finished with exit code 0이라는 문구와 함께 프로그램이 종료되는 문제점이 있었다. 즉, 프로그램을 실행시킨 후에 특정 코드에 대해서도 테스트해보고 싶어도 특정 구문만 모두 돌아간 후에는 프로그램이 종료되는 바람에 다른 코드를 확인해볼 수 없었다. 따라서 이번 게시글에서는 특정 구문이 모두 돌아간 후에도 프로그램이 종료되지 않도록 하기 위해 PyQt5 모듈을 활용하여 GUI와 연결해보고자 한다. 물론 `while True:` 구문을 통해 프로그램이 계속해서 동작하게끔 구현할 수 있긴 하지만, 결국 프로그램을 테스트하는 데에 있어서는 GUI가 많은 부분에서 큰 유용성을 가져다 주기 때문에 시간이 더 걸려서 돌아가는 것 같더라도 Qt Designer를 사용해보도록 하자.

 

1. PyQt5 설치하고 GUI 파일 만들기

해당 프로그램을 설치하는 방법에 대해서는 별도로 설명하지 않았는데, 설치 방법은 간단하다. 파이썬 IDLE 또는 파이참 하단의 터미널(아나콘다 가상환경을 사용할 경우에는 Anaconda Prompt)을 통해 설치해주면 되는데, 아래의 문구를 사용하면 설치가 시작된다.

  • pip install pyqt5

본인의 경우에는 아나콘다를 통해 가상환경을 생성한 후, 그 가상환경을 파이참의 Interpreter로 하여 코드를 구현하고 있기 때문에 Anaconda Prompt를 통해 PyQt5를 설치하였다. 따라서 앞서 설치한 designer.exe 파일은 anaconda3 - Library - bin 내부에 위치해 있다. 이제 이 아이콘을 우클릭한 후에 바탕화면에 바로가기를 클릭하여 바로가기 아이콘을 생성하고 바로 더블클릭을 해서 Qt Designer를 실행해주도록 하자.

이제 프로그램이 실행되면 아래와 같은 창이 뜨는데, 여기서 Main Window를 클릭한 후 생성(R)을 누르면 하단의 오른쪽과 같은 빈 화면이 생성된다. 버튼을 생성하거나 하는 등 기능을 살펴보는 것은 나중에 보기로 하고, 일단은 이 파일을 바탕화면에 main이라는 이름으로 저장한 후에 이전에 프로젝트를 생성한 폴더에 같이 넣어주어야 한다. 왜냐하면 아래의 2번째 단계에서 구현할 코드 자체가 Boss.py 파일과 GUI 파일이 같은 폴더에 있어야만 작동하기 때문이다.

이제 main.ui 파일을 아래의 이미지와 같은 모습이 나오도록 Boss.py 파일과 같은 경로에 넣어주도록 하자.

 

 

2. PyQt5의 Qt Designer를 통해 코드와 연결하기

이제 같은 폴더에 넣어주었다면 가장 먼저 필요한 모듈들을 `import`해주도록 하자.
※ Line: 11~13

## Boss.py ##
import win32com.client
from pywinauto import application
from COM import CpSysDib
from COM import CpUtil
from COM import CpTrade
from COM import DsCbo1
import time

## GUI ##
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import *

이제 Boss.py 파일과 같은 폴더에 넣어주었던 main.ui 파일을 파이썬 내부에서 호출하는 코드가 필요한데, 그 코드는 `uic` 모듈의 `loadUiType` 함수를 통해 불러올 수 있다. 아래의 코드를 확인해보자.
※ Line: 15~17

## Boss.py ##
import win32com.client
from pywinauto import application
from COM import CpSysDib
from COM import CpUtil
from COM import CpTrade
from COM import DsCbo1
import time

## GUI ##
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import *

main_ui = uic.loadUiType("main.ui")
print(main_ui)
print(main_ui[0])

▶ 실행 결과 확인하기

더보기

(<class 'Ui_MainWindow'>, <class 'PyQt5.QtWidgets.QMainWindow'>)
<class 'Ui_MainWindow'>

위의 결과값만 봐도 어렵지 않게 파악할 수 있겠지만, `main_ui` 변수 내에는 두 개의 데이터가 입력되어 있다. 두 데이터 중 첫 번째 데이터인 `main_ui[0]`이 <class 'Ui_MainWindow'>이고, 두 번째 데이터인 `main_ui[1]`이 <class 'PyQt5.QtWidgets.QMainWindow'>인데, 우리는 이 중 첫 번째 데이터인 <class 'Ui_MainWindow'>를 `class cybos`의 파라미터로 전달해주어야 한다. 전달하는 방식은 아래와 같이 두 가지 방식이 있을 것이다. 어떠한 방식을 사용하든지 간에 실질적으로 전달하게 되는 데이터는 동일하기 때문에 상관없으므로 아무 방식이나 사용해도 된다. 이후에 올릴 코드들은 두 번째 방식에 따라 작성되어 있긴 하지만, 첫 번째 방식으로 작성해도 전혀 상관이 없으니 편한 방식을 사용하면 된다.

## 첫 번째 방식
main_ui = uic.loadUiType("main.ui")
class cybos(main_ui[0]):
## 두 번째 방식
main_ui = uic.loadUiType("main.ui")[0]
class cybos(main_ui):

이제 `class cybos`의 인자로 `main_ui`를 전달해주었으니 다 된 것 같지만, `class cybos`가 GUI를 띄우기 위해서는 이외에도 `QMainWindow`라는 인자를 전달해주어야 한다. 이 인자는 `from PyQt5.QtWidgets import *` 내에서 이미 호출되었다.

## Boss.py ##
import win32com.client
from pywinauto import application
from COM import CpSysDib
from COM import CpUtil
from COM import CpTrade
from COM import DsCbo1
import time

## GUI ##
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import *

main_ui = uic.loadUiType("main.ui")[0]
class cybos(QMainWindow, main_ui):

여기까지 코드를 모두 작성했는데, `class cybos` 바로 아래에 있는 `def __init__(self):` 부분의 색이 노란색으로 바뀌었다는 걸 확인할 수 있다. 왜 그럴까 ?

 

 


반응형
728x90

 

 

오류 내용을 보니 아래와 같이 Add super class call이라는 문구가 출력되고 있는데, 이는 `super().__init__()` 구문으로 해결할 수 있다. 
※ Line: 18

## Boss.py ##
import win32com.client
from pywinauto import application
from COM import CpSysDib
from COM import CpUtil
from COM import CpTrade
from COM import DsCbo1
import time

## GUI ##
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import *

main_ui = uic.loadUiType("main.ui")[0]
class cybos(QMainWindow, main_ui):
    def __init__(self):
        super().__init__()

여기까지 모든 코드를 잘 구현했다면, 맨 아래에 있는 if __name__ == "__main__": 구문 아래를 다음과 같이 수정해주도록 하자. 
※ Line: 6~10

## 기존 코드
if __name__ == "__main__":
    cybos()
    
## 변경 후 코드
if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWindow = cybos()
    myWindow.show()
    app.exec_()

 

이제 파이썬 코드를 실행시켜보면 로그인 절차를 모두 수행한 후에 아래와 같은 자그마한 창을 하나 띄우게 된다. 이 자그마한 창이 우리가 앞전에 main.ui라는 이름으로 생성한 GUI 파일이며, 이제부터는 Process finished with exit code 0라는 문구가 출력되지 않고 프로그램이 계속해서 동작 상태에 머무르게 된다. 

▶ 실행 결과 확인하기

더보기

[통신결과:0] 서버와의 연결에 실패했습니다.
[통신결과:0] 서버와의 연결에 실패했습니다.
로그인되어 있지 않습니다. 로그인을 시도합니다.
[통신결과:0] 서버와의 연결에 실패했습니다.
로그인되었습니다. 반복문에서 나갑니다.
[A005930] 삼성전자
  전일종가:78300, 현재가:77700 
  시가:77700, 고가:78400, 저가:77500

이후에 GUI 창의 우측 상단에 있는 X 버튼을 눌러서 직접적으로 종료를 시켜줘야만 Process finished with exit code 0라는 문구가 출력되면서 프로그램이 종료되었다는 신호를 보내준다는 것을 알 수 있다. 이는 다시 말하자면 GUI가 종료되지 않는다면 프로그램은 온전하게 종료되지 않는다는 것이며 GUI가 프로그램의 종료를 억제하고 있다는 것을 의미한다.

 

 


728x90
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.