PyQT로 GUI 짜보기

kpark2000·2024년 7월 29일

업비트에서 API를 연결해서 시스템 트레이딩을 했었는데. 그 때 Docker처럼 종목별로 프로그램을 띄웠다 내렸다 할 수 있도록 맞춤형 GUI를 개발했었다. 그러나 지금 와서 까보니 로직은 안붙이고 그림만 그려 놨더라. 한 때 QT에 빠져 살았었는데. 지금도 QT가 좋고 언젠가 애인이 생긴다면 연락처에 '큐티'가 아닌 'QT'로 저장해두겠다.

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
import pymongo

class MongoDBApp(QMainWindow):
    def __init__(self):
    	# QMainWindow 인스턴스 생성
        super().__init__()
        # 윈도우 창 제목 세팅
        self.setWindowTitle("Controls")
        # 윈도우 창 크기 세팅
        self.setGeometry(100, 100, 800, 600)
        # 안에 위젯 그려주기
        self.initUI()

    def initUI(self):
    	# QWidget 객체 생성
        main_widget = QWidget()
        # 윈도우에 위젯 할당
        self.setCentralWidget(main_widget)
        # 위젯에 레이아웃 설정 (Top-Down)
        layout = QVBoxLayout(main_widget)
        # GroupBox 생성
        search_group_box = self.create_search_views()
        # 레이아웃에 GroupBox 추가하기
        layout.addWidget(search_group_box)
        # Table 생성
        self.table_widget = QTableWidget()
        # 테이블 컬럼 수 세팅
        self.table_widget.setColumnCount(3)
        # 테이블 헤더 명 세팅
        self.table_widget.setHorizontalHeaderLabels(["Market", "Ticker", "Stage"])
        # 컬럼 넓이 균등하게 만들기
        self.table_widget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        # 기본으로 들어가는 행 선택 시 파랗게 색칠 들어가는 거 없애기
        self.table_widget.setSelectionMode(QTableWidget.NoSelection)
        # 기본으로 들어가는 행 선택 시 outline 되는 기능 없애기
        self.table_widget.setFocusPolicy(Qt.NoFocus)
        # 기본으로 들어가는 셀 편집 기능 없애기
        self.table_widget.setEditTriggers(QTableWidget.NoEditTriggers)
        # 레이아웃에 Table 추가하기
        layout.addWidget(self.table_widget)
        # 몽고DB에서 Table에 뿌릴 데이터 불러오기
        self.fetch_data_from_mongodb()
        
    def create_search_views(self):
    	# GroupBox 생성
        group_box = QGroupBox("Search Box")
        # 레이아웃 세팅 (Column-style)
        search_layout = QVBoxLayout(group_box)
        # 하위 레이아웃 생성 (Row-style)
        label_and_bar_layout = QHBoxLayout()
        # Label 생성
        label = QLabel("Ticker: ")
        # LineEdit 생성
        self.search_ticker = QLineEdit()
        # 하위 레이아웃에 Label 추가하기
        label_and_bar_layout.addWidget(label)
        # 하위 레이아웃에 LineEdit 추가하기
        label_and_bar_layout.addWidget(self.search_ticker)
        # PushButton 생성
        search_button = QPushButton("Run")
        # PushButton 넓이 세팅
        search_button.setFixedWidth(100)
        # PushButton 위치를 레이아웃의 오른쪽으로 밀어넣기
        search_button.setLayoutDirection(Qt.RightToLeft)
        # PushButton에 onClick 액션 달아주기
        search_button.clicked.connect(self.search_data)
        # GroupBox 레이아웃에 Label과 LineEdit이 들어있는 하위 레이아웃 추가하기
        search_layout.addLayout(label_and_bar_layout)
        # GroupBox 레이아웃에 PushButton 추가하기
        search_layout.addWidget(search_button)
        # GroupBox 객체 리턴
        return group_box
    
    def fetch_data_from_mongodb(self):
    	# 몽고DB Connection 생성
        client = pymongo.MongoClient("mongodb://localhost:27017/")
        # 데이터베이스 레퍼런싱
        db = client["local"]
        # 콜렉션 레퍼런싱
        collection = db["tickers"]
        # find() 메소드로 Cursor 반환
        data = collection.find().sort("ticker", pymongo.ASCENDING)
        # 테이블에 뿌려주는 메소드 호출
        self.populate_table(data)

    def populate_table(self, data):
    	# Cursor를 iterate하여 행을 한개씩 추가해주기 위해 디폴트 행 수를 0으로 세팅
        self.table_widget.setRowCount(0)
        # Cursor 루프 시작
        for row_index, item in enumerate(data):
        	# 행마다 들어갈 PushButton 생성
            button = QPushButton("Normal")
            # setStyleSheet 메소드로 CSS 추가
            button.setStyleSheet("background-color: green; color: white;")
            # onClick 콜백 생성
            button.clicked.connect(lambda _, row=row_index: self.on_button_clicked(row))
            # Table에 row_index 걸고 행 추가
            self.table_widget.insertRow(row_index)
            # 새로 생성된 행의 0번 cell에 값 채우기
            self.table_widget.setItem(row_index, 0, QTableWidgetItem(item["market"]))
            # 새로 생성된 행의 1번 cell에 값 채우기
            self.table_widget.setItem(row_index, 1, QTableWidgetItem(item["ticker"]))
            # 새로 생성된 행의 2번 cell에 값 채우기
            self.table_widget.setCellWidget(row_index, 2, button)
    
    def on_button_clicked(self, row):
    	# 콜백 함수 매개변수로 받은 row의 2번 cell 레퍼런싱
        button = self.table_widget.cellWidget(row, 2)
        # PushButton 객체에 text() 메소드를 실행하여 문구 추출
        button_text = button.text()
        # 문구가 'Normal'인 경우
        if button_text == "Normal":
        	# PushButton 객체의 문구 세팅
            button.setText("Forcing")
            # PushButton 객체의 CSS 세팅
            button.setStyleSheet("background-color: red; color: white;")

    def search_data(self):
    	pass

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MongoDBApp()
    window.show()
    sys.exit(app.exec_())
profile
초보자를 위한 프로그래밍 정리

0개의 댓글