☀️ 운영체제 : macos
☀️ Tools : VScode, mariaDB, Sequel Pro
☀️ DATA : 제공하지 않음
* Sequel Pro, home brew, macos 등 사용하지 않는 사람에게는 권장하지 않음
아래 링크의 day01 과 이어집니다
https://mealhouse.tistory.com/9
지난 시간에는 datasave.py 파일을 만들어 data가 1분마다 저장되며,
기존의 오래된 data는 삭제되는 형식의 프로그램을 제작해 보았습니다.
이번에는 직접 data를 시각화하여 볼 수 있는 프로그램을 qt를 활용하여 제작해보도록 하려고 합니다.
일반적으로 한번에 많은 라이브러리를 설치해 두는것보다
각 용도에 맞는 라이브러리를 설치할 수 있는 가상환경을 구축하여
해당 가상환경 안에서의 실행을 권장드립니다.
+ mariaDB 관련한 사항은 위 링크로 확인할 수 있습니다.
+ tensorflow, keras 등 머신러닝에 대한 지식이 전무한 분들은 이해하기 어려울 수 있습니다.(두가지 라이브러리가 무엇인지에 대한 공부만이라도 하는 것을 권장합니다.)
1. 필요한 라이브러리 호출
아래는 qt 활용에 있어 필요한 라이브러리 모음입니다.
import pandas as pd
import numpy as np
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib import font_manager, rc
import pymysql
import tensorflow as tf
import keras
from keras.models import Sequential
from keras.layers import SimpleRNN, LSTM, GRU, Dropout, Dense
from sklearn.preprocessing import MinMaxScaler
numpy : 각종 연산을 쉽게 도와줄 수 있는 라이브러리
matplotlib : 그래프 작성에 필요한 라이브러리
tensorflow, keras : 머신러닝에 활용
MinMaxScaler : 데이터 정규화에 필요한 라이브러리
이외의 구성 라이브러리 중 모르는 것이 있으면 개별로 찾아보시면 공부에 도움이 되니 참고 바랍니다.
2. python 을 활용한 qt 기본 틀 생성
class MyApp(QWidget) :
def __init__(self) :
super().__init__()
self.initUI()
def initUI(self) :
if __name__ == '__main__' :
app = QApplication(sys.argv)
ex = MyApp()
sys.exit(app.exec_())
위 코드는 qt 기본 틀 생성 이전에 선언해주는 클래스와 생성자 호출,
어플리케이션의 동작과 종료 등을 구성하는 기본적인 코드입니다.
해당 코드는 별도의 개인 라이브러리로 저장해두고 관리하면 편리합니다.
이제 MyApp 클래스 안의 initUI 함수에 각종 레이아웃과 기능 등을 추가하며 진행하면 됩니다.
필자는 처음 qt를 배울 때 designer 를 활용하면서
레이아웃과 위젯 등을 내가 원하는 위치에 배치한 후
코드를 수정하는 방식으로 배웠습니다.
이러한 방식도 좋지만 최초 배치한 레이아웃과 위젯 등의 위치나 기타 기능등을 다시 수정하려면
UI 를 designer로 변경한 후 코드를 수정하는 것이 편하게 되는데,
designer와 같이 진행을 하다보면 내가 중간까지 짠 코드를 어디에 삽입하고
어느 부분을 수정해야 하는지 상당히 복잡하고 어려웠습니다.
pyqt에 대해 조금만 검색해보면 나오는 정보들은 대부분 위 코드와 같이 최초 생성되는 qt 틀을 구성하고
함수 안에 레이아웃을 짜면서 진행하니, 이러한 방식으로 qt 를 제작하는 것에 대한 공부를 적극 권장드립니다.
코드로 qt 틀을 짜면서 편리해지는 것은
레이아웃의 위치 등을 명시해 주지 않아도 윈도우 창에 맞추어 레이아웃들이 배치되어
designer로 배치하는 것보다 정확하고 균등하게 위치시킬 수 있습니다.
우리가 통상적으로 '그림을 그린다'의 개념은
하나의 도화지 위에 연필, 색연필 등을 통해 다른 색으로 틀을 짜고 색을 채우는 등의 행위로 생각하지만,
개인적으로 포토샵이나 프로그램에서의 '그림을 그린다'의 개념은 조금 다르다고 생각합니다.
하나의 도화지 위에 그리는 것이 아니라,
각종 그림을 각각의 종이로 만들어 큰 도화지 위에 붙인다 라고 생각하고 있습니다.
즉, 광활한 사막 위에 서 있는 사람을 그리고 싶다면
광활한 사막 이미지 배경을 큰 도화지에 채우고, 사람을 별개의 종이에 그리고 오려내어
그 위에 덧붙인다고 생각하면 됩니다.
서두가 너무 길어졌는데 기본적인 개념의 경우 다른 곳의 정보를 참고하시길 바라겠습니다.
3. DB 커넥트
self.conn = pymysql.connect(hots = '127.0.0.1', user = USER, password = PASSWORD, db = DBNAME)
self.cursor = self.conn.cursor()
initUI 함수 바로 첫부분에 DB 커넥트 및 커서 설정을 해주고,
최종 데이터를 불러오는 단계에서 쿼리문 실행을 진행합니다.
4. 데이터 테이블 생성
self.tbltemporg = QTableWidget(100, 7) # 테이블 (100행 7열)
col_head = ['Date', 'temp1', 'temp2', 'temp3', 'temp4', 'temp5', 'temp6']
self.tbltemporg.setHorizontalHeaderLabels(col_head) # setHorizontalHeaderLabels : 열이름 설정
보유중인 데이터가 날짜, temp1 - 6 으로 총 7개의 열을 가지고 있고
테이블의 행 개수의 경우 너무 많은 데이터를 띄우기엔 시간 소요가 필요하니 100행으로 임시 제한합니다.
해당 테이블의 경우 우리가 추후 쿼리문을 통해 1분마다 불러오는 1개 레코드의 모습을 띄울 예정입니다.
5. 로그데이터 표시 창 생성
self.txtLog = QTextEdit()
self.txtLog.setReadOnly(True)
self.txtLog.append('이 부분에 로그데이터가 표시됩니다')
QTextEdit : text edit 창 생성
setReadOnly(True) : 읽기 전용, 쓰기 불가
위와 같이 text edit을 생성하여 불러들이는 데이터에 대한 로그 데이터를 표기합니다.
6. 레이아웃 생성 및 배치
layout = QHBoxLayout() # 최상위 레이아웃(QHBoxLayout : 수평배열)
layoutMonitor = QVBoxLayout() # 수직배열 레이아웃(QVBoxLayout : 수직배열)
layoutML = QVBoxLayout() # 수직배열 레이아웃
# 왼쪽 레이아웃 및 위젯 생성
layoutMenu = QHBoxLayout() # 메뉴 레이아웃
layoutTbl = QHBoxLayout() # 테이블 레이아웃
layoutGraph = QVBoxLayout() # 그래프 레이아웃
layoutTbl.addWidget(self.tbltemporg) # 앞서 만든 테이블 위젯 추가
layoutTbl.addWidget(self.txtLog) # 로그 텍스트 위젯 추가
layoutGraph.addWidget(self.canvas) # 그림 그리는 영역 위젯 추가
layoutMonitor.addLayout(layoutMenu)
layoutMonitor.addLayout(layoutTbl)
layoutMonitor.addLayout(layoutGraph)
# 오른쪽 레이아웃 및 위젯 생성 : 3행 2열의 배치로 그래프 그릴 영역
layoutTemp1 = QHBoxLayout()
layoutTemp2 = QHBoxLayout()
layoutTemp3 = QHBoxLayout()
layoutTemp1.addWidget(self.canvas1) # 1번 그래프 영역 추가
layoutTemp1.addWidget(self.canvas2) # .
layoutTemp2.addWidget(self.canvas3) # .
layoutTemp2.addWidget(self.canvas4) # .
layoutTemp3.addWidget(self.canvas5) # .
layoutTemp3.addWidget(self.canvas6) # 6번 그래프 영역 추가
# ======== 1번 레이아웃에 1,2번 그래프 영역 위젯 추가 : 1행에 2열짜리 영역 생성 =========
layoutML.addLayout(layoutTemp1)
layoutML.addLayout(layoutTemp2)
layoutML.addLayout(layoutTemp3)
layout.addLayout(layoutMonitor)
layout.addLayout(layoutML)
그래프 6개를 그리는 영역에 있어 추가 설명 후 넘어가자면
그래프 6개를 포함하는 하나의 레이아웃을 크게 생성하고
다시 QVBoxLayout() 으로 수직 구조의 레이아웃을 생성합니다.
그럼 하나의 긴 박스 안에 다시 3행의 박스 레이아웃이 생기는데
그렇게 생긴 박스 1개당 그래프 영역 2개를 넣어 주어 최종적으로 3행 2열의 그래프로 6개를 표현합니다.
이와 같이 순수하게 ~행 ~열의 레이아웃을 나누어 그림을 그릴 수 있지만,
Qt에서는 GridLayout 이란걸 제공합니다.
레이아웃에 QGridLayout()을 적용하여 그리면 손쉽게 그릴 수 있으며
layoutML.addLayout(layoutTemp1, 0, 0) 과 같이 추가 할 레이아웃에 (넣을 레이아웃, 행, 열) 등을
기입하면 자동으로 그리드를 나누어 일정한 간격으로 적용시킵니다.
7. 그래프 영역 지정
self.fig = plt.Figure(figsize=(6,6)) # 그래프 영역 변수 생성
self.canvas = FigureCanvas(self.fig) # 그래프 그리기 영역
self.fig1 = plt.Figure(figsize=(7,3))
self.fig2 = plt.Figure(figsize=(7,3))
self.fig3 = plt.Figure(figsize=(7,3))
self.fig4 = plt.Figure(figsize=(7,3))
self.fig5 = plt.Figure(figsize=(7,3))
self.fig6 = plt.Figure(figsize=(7,3))
self.canvas1 = FigureCanvas(self.fig1) # 그래프 그리기 영역
self.canvas2 = FigureCanvas(self.fig2) # 그래프 그리기 영역
self.canvas3 = FigureCanvas(self.fig3) # 그래프 그리기 영역
self.canvas4 = FigureCanvas(self.fig4) # 그래프 그리기 영역
self.canvas5 = FigureCanvas(self.fig5) # 그래프 그리기 영역
self.canvas6 = FigureCanvas(self.fig6) # 그래프 그리기 영역
이전에 존재하지 않았던 그래프 그리기 영역의 위젯들을
위의 self.canvas 변수를 활용하여 그려주고 적용시킵니다.
8. 최종 틀 마무리
self.setLayout(layout) # 최상위 레이아웃 세팅
self.setWindowTitle('TempMonitor') # setWindowTitle : 생성되는 윈도우의 타이틀 설정
self.setGeometry(0, 30, 1600, 900) # setGeometry : 생성되는 윈도우의 좌표 및 크기 설정(x, y, 너비, 길이)
self.show()
9. 최종 실행된 모습
3 ~ 8번 까지의 순서는 initUI 함수에 진행 순에 맞게 넣어주면 되며,
레이아웃과 위젯 관련된 순서에는 굉장히 큰 영향은 없지만
이런 경우는 문제가 됩니다
ex) 위젯을 만들고 레이아웃에 추가 후 레이아웃 생성 => 레이아웃이 먼저 생성이 되어야 맞기 때문에 오류 발생
그렇기에 레이아웃 -> 위젯 생성 -> 레이아웃에 위젯 추가 등의 생성되는 순 혹은 진행되는 순으로 정리하며 작성하는 것이 좋습니다.
사실 위의 코드도 진행순으로 한다면 오류가 발생할 것입니다.
이 부분은 스스로 생각하면서 어떻게 해야 윈도우 창이 나타날지 실행 연습해 보시길 권합니다.
QT의 틀은 이렇게 잡아두고 추후 데이터를 불러오며 해당하는 데이터에 대한 머신러닝 학습과
학습을 통해 나오는 결과와 그래프 등을 직접 불러오는 과정을 진행해보겠습니다.
+ 진행하는데 있어 필자가 겪은 오류 혹은 어떤 방식이 더 좋은점에 대해서도 개인 의견 남겨두도록 하겠습니다.
+ 앞서 진행한 그래프 그리는 영역에 있어 필자는 3개의 레이아웃에 그래프를 2개씩 넣으며 진행했으나,
QGridLayout을 통해 조금 더 편리하게 진행할 수 있으니 이러한 방식도 있다는 것을 참고해주세요.
'Temp_Monitor Projects' 카테고리의 다른 글
【 Machine Learning Project_01 】 Temp_Monitor : day03 QT 데이터프레임, 로그데이터 삽입 (1) | 2023.01.01 |
---|---|
【 Machine Learning_Project01 】Temp_Monitor : day01 (0) | 2022.12.22 |