from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5.QtWidgets import QToolButton, QSizePolicy
import datetime
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cv2
import os
class MainDialog(QtWidgets.QWidget):
'''메인 윈도우가 되는 위젯. 이 창에서 나머지 기능들을 팝업시킵니다.'''
def __init__(self):
super().__init__()
self.layout_s = QtWidgets.QVBoxLayout(self) #전체틀
self.start_layout = QtWidgets.QHBoxLayout() #버튼을 담을 틀
self.setFixedSize(300, 200)
self.btn_watch = self.createButton("공부 시작",self.clickWatch)#버튼watch
self.btn_graph = self.createButton("공부량 보기",self.clickGraph)#버튼graph
self.btn_watch.resize(self.btn_watch.sizeHint())#sizeHint=holds the recommended size for the widget
self.btn_graph.resize(self.btn_graph.sizeHint())
self.start_layout.addWidget(self.btn_watch)#틀에 버튼 담음
self.start_layout.addWidget(self.btn_graph)
self.layout_s.addLayout(self.start_layout)#전체틀에 버튼을 담은 틀을 담음
self.setLayout(self.layout_s)
self.show()
def clickWatch(self):
'''공부 시작이 눌리면 동작하는 함수'''
# MyClock 객체가 생성되어 newWindow 변수에 저장
self.newWindow = MyClock()
# 새로운 위젯 show
self.newWindow.show()
def clickGraph(self):
try:
image = cv2.imread("C:\\study\\chart.png", cv2.IMREAD_ANYCOLOR)
cv2.imshow("study time", image)
cv2.waitKey(0)#cv2.waitkey(time)이며 time마다 키 입력상태를 받아옵니다.
#0일 경우, 지속적으로 검사하여 해당 구문을 넘어가지 않습니다.
cv2.destroyAllWindows()#창 닫기
except:
QtWidgets.QMessageBox.about(self, "알림", "공부하세요!")
def createButton(self, text, function):
button = Button(text)
button.clicked.connect(function)
return button
class MyClock(QtWidgets.QWidget):
def __init__(self):
super().__init__()
# 스톱와치 용 변수
self.createFolder("C:\\study")
self.watch_start_time = 0
self.mouseClick = False
self.setWindowTitle("시계")
self.setFixedSize(250, 100)#사이즈고정
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)#타이틀바 없앰
self.initWidgets()
self.show()
self.days = datetime.date.today().day
self.months=datetime.date.today().month
def createFolder(self,directory):
try:
if not os.path.exists(directory):
os.makedirs(directory)
except OSError:
print("error")
def keyPressEvent(self, e):#esc누르면 종료
if e.key() == QtCore.Qt.Key_Escape:
day = str(self.months)+"/"+str(self.days)
try:#이미 파일을 만들었으면
data = pd.read_csv('C:\\study\\graph.csv')
if data.loc[len(data)-1, "day"]==day:#같은 날짜면 시간 누적
data.loc[data["day"]==day, "time"]+=self.watch_start_time
data.to_csv('C:\\study\\graph.csv',header=True, index=False)
else:#새로운 날짜,시간 append
data2=pd.DataFrame({"day":[day],"time":[self.watch_start_time]})
data=pd.concat([data,data2], ignore_index=True)
data.to_csv('C:\\study\\graph.csv',header=True, index=False)
except:#파일이없으면
df=pd.DataFrame({"day":[day],"time":[self.watch_start_time]})
df.to_csv('C:\\study\\graph.csv',header=True, index=False)#header:column이름 정보
data=pd.read_csv('C:\\study\\graph.csv')
group_by_day=data.groupby('day').time.sum()#day별로 time의 합을 구함
y=list(group_by_day)
x = np.arange(len(y))
xlabel = list(data["day"])
plt.title("Amount",fontsize=20)
plt.bar(x, y)
plt.xticks(x, xlabel)
plt.yticks(sorted(y))
plt.xlabel("Date",fontsize=10)
plt.ylabel("Study Time(s)",fontsize=10)
plt.savefig('C:\\study\\chart.png')#그래프 저장
self.close()
def mousePressEvent(self, e):#마우스로 창 누를때
if e.button() == QtCore.Qt.LeftButton:#좌클릭시
self.mouseClick = True
self.oldPos = e.globalPos()#x,y가 튜플형태로 넘어옴
#globalPos=윈도우상의 x,y좌표
def mouseReleaseEvent(self, e):
self.mouseClick = False
def mouseMoveEvent(self, e):#마우스로 창 누른뒤 이동시킬때
if self.mouseClick:
delta = QtCore.QPoint(e.globalPos() - self.oldPos)
self.move(self.x() + delta.x(), self.y() + delta.y())
self.oldPos = e.globalPos()
def initWidgets(self):
self.layout = QtWidgets.QVBoxLayout(self) #QV=가로 QH=세로
# 시작, 초기화 버튼 2개를 HBoxLayout 에 추가합니다.
self.button_layout = QtWidgets.QHBoxLayout() # 버튼을 담기위한 레이아웃
self.btn_start = QtWidgets.QPushButton("중지", self)
self.btn_reset = QtWidgets.QPushButton("초기화", self)
self.btn_start.resize(self.btn_start.sizeHint())
self.btn_reset.resize(self.btn_start.sizeHint())
self.button_layout.addWidget(self.btn_start)
self.button_layout.addWidget(self.btn_reset)
self.lcd = QtWidgets.QLCDNumber()#시계디자인 위젯
self.lcd.setSegmentStyle(QtWidgets.QLCDNumber.Flat)#글자평평하게
self.lcd.setDigitCount(8)#글자 총 8개까지 보여줌(hh:mm:ss)
self.lcd.setFrameStyle(QtWidgets.QFrame.NoFrame)#박스없앰
self.timer = QtCore.QTimer() # 타이머 생성
# 스탑와치용 출력 함수 연결
self.timer.timeout.connect(self.showWatch) # 타임아웃 이벤트를 showWatch와 연결
# 정한 시간이 지날때마다 show_time 실행
self.timer.start(1000)#1초에 한번씩
self.resetWatch()
self.layout.addWidget(self.lcd)
# 버튼 레이아웃을 기본 레이아웃에 추가합니다.
self.layout.addLayout(self.button_layout)
self.setLayout(self.layout)
self.btn_start.clicked.connect(self.startWatch)
self.btn_reset.clicked.connect(self.resetWatch)
def startWatch(self):
'''스탑와치를 시작하는 함수 입니다.
버튼 클릭시 시작과 중지를 한 버튼으로 처리하기 위해
버튼의 글자를 가져와서 각 상황에 맞게 동작합니다.'''
text = self.btn_start.text()
if text == "시작":
self.btn_start.setText("중지")
self.timer.start(1000)
elif text == "중지":
self.btn_start.setText("시작")
self.timer.stop()
def resetWatch(self):
'''스탑와치를 초기화 합니다.'''
text = "00:00:00"
self.watch_start_time = 0
self.lcd.display(text)
def showWatch(self):
'''스탑와치의 현재시간 - 시작시간을 계산해서 화면에 출력하는 함수'''
# 현재시간 - 스탑와치 시작시간을 total_seconds() 로 변환해서 초만 받습니다.
self.watch_start_time+=1
# 진행된 초를 시:분:초로 출력하기 위해서 계산합니다.
hour = self.watch_start_time // 3600
minute = self.watch_start_time % 3600 // 60
second = self.watch_start_time % 60
# 시:분:초 형태로 문자열 포맷팅을 합니다.
text = '{:02d}:{:02d}:{:02d}'.format(hour, minute, second)
# 출력
self.lcd.display(text)
class Button(QToolButton):
def __init__(self, text):
super().__init__()
buttonStyle = '''
QToolButton:hover {border:1px solid #0078d7; background-color:#e5f1fb;}
QToolButton:pressed {background-color:#a7c8e3}
QToolButton {font-size:11pt; font-family:나눔고딕; border:1px solid #d6d7d8; background-color:#f0f1f1}
'''
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
self.setText(text)
self.setStyleSheet(buttonStyle)
def sizeHint(self):
size = super(Button, self).sizeHint()
size.setHeight(size.height() + 30)
size.setWidth(max(size.width(), size.height()))
return size
if __name__ == '__main__':
app = QtWidgets.QApplication([])
win=MainDialog()
app.exec_()