본문 바로가기

Python/개발일지

파이썬 예제[Python] wxpython , sqlite3이용해서 일기장 만들기

한 5일동안 만들었다.

아직 완성은 아니지만, 뭐 완성품 올리는 블로그도 아니고, 꽤 잘 작동해서 올리게 되었다.

 

DbManager.py이다.

import sqlite3
import arrow
import os

class DbManager:
    def __init__(self):
        self.conn = sqlite3.connect(os.path.join(os.path.expanduser('~'), 'documents', 'Diary', 'Diary.db'))
        self.c = self.conn.cursor()

    def saveDiaryInfo(self, date, time, todayFeel, todayThoughtsCount, writer):
        sql = f'INSERT INTO Diary (date, time, todayFeel, TodayThoughtsCount, Writer) VALUES ("{date}","{time}", {todayFeel}, "{todayThoughtsCount}", "{writer}")'
        try:
            self.c.execute(sql)
        except:
            self.deleteDiaryInfo(date)
            self.c.execute(sql)
        self.conn.commit()
        
    def readDiaryInfo(self, date, userId):
        sql = f'SELECT * FROM Diary WHERE date = "{date}" and Writer = "{userId}"'
        self.c.execute(sql)
        self.conn.commit()
        return self.c.fetchone()

    def deleteDiaryInfo(self, date):
        sql = f'DELETE FROM Diary WHERE date = "{date}"'
        self.c.execute(sql)
        self.conn.commit()

    def closeDb(self):
        self.conn.commit()
        self.c.close()
        self.conn.close()
    
    def saveUserInfo(self, id, pw, sQuestionNum, answer):
        sql = 'INSERT INTO User (ID, PW, sQuestionNum, answer) VALUES ("{0}","{1}", {2}, "{3}")'.format(id, pw, sQuestionNum, answer)
        try:
           self.c.execute(sql)
        except:
            print("이 계정은 이미 있습니다.")
            return -1
        self.conn.commit()
        return 0

    def readAllId(self):
        sql = f'SELECT ID FROM User'
        self.c.execute(sql)
        self.conn.commit()
        return self.c.fetchall()

    def findDiaryWithCondition(self, startDate, finishDate, startFeelRange, finishFeelRange, thoughtsStartRange, thoughtsFinishRange, userId):
        sql = f'SELECT * FROM Diary WHERE Writer = "{userId}" and todayFeel >={startFeelRange} and todayFeel<={finishFeelRange} and TodayThoughtsCount>={thoughtsStartRange} and TodayThoughtsCount<={thoughtsFinishRange} '#and CAST(strftime("%s", Date) AS integer )>=CAST(strftime("%s", {startDate}) AS integer ) and CAST(strftime("%s", Date) AS integer )<=CAST(strftime("%s", {finishDate}) AS integer )'
        self.c.execute(sql)
        self.conn.commit()
        return self.c.fetchall()

    def readUserPw(self, id):
        sql = f'SELECT PW FROM User WHERE ID = "{id}"'
        self.c.execute(sql)
        self.conn.commit()
        return self.c.fetchone()

    def readUsersQuestionNum(self, id):
        sql = f'SELECT sQuestionNum FROM User WHERE ID = "{id}"'
        self.c.execute(sql)
        self.conn.commit()
        return self.c.fetchone()

    def readUserAnswer(self, id):
        sql = f'SELECT answer FROM User WHERE ID = "{id}"'
        self.c.execute(sql)
        self.conn.commit()
        return self.c.fetchone()

    def deleteUserInfo(self, id):
        sql = f'DELETE FROM User WHERE ID = "{id}"'
        self.c.execute(sql)
        self.conn.commit()

    def readUserIdByQA(self, sQuestionNum, answer):#sQuestionNum이랑 answer로 id찾는 함수
        sql = f'SELECT id FROM User WHERE answer = "{answer}" AND sQuestionNum = "{sQuestionNum}"'
        self.c.execute(sql)
        self.conn.commit()
        return self.c.fetchone()
        
    
    def updatePw(self, id, newPw):
        sql = f'UPDATE Diary SET PW = "{newPw}" WHERE ID = "{id}"'
        self.c.execute(sql)
        self.conn.commit()
    
        
if __name__ == "__main__":
    #TestCase
    a = DbManager()
    a.saveDiaryInfo(arrow.now().date(), str(arrow.now().time())[:5], 1, 4)    
    print(a.readDiaryInfo(arrow.now().date()))
    a.saveUserInfo('qwerty', 'qwertyuiop1', 1, 'qwerty')
    print(a.readAllID())
    print(a.readUserPw('qwerty'))
    print(a.readUsersQuestionNum('qwerty'))
    print(a.readUserAnswer('qwerty'))
    '''
    for i in range(400):
        a.deleteDiaryInfo(str(i))
        a.deleteUserInfo(str(i))
    
    for i in range(400):
        a.saveDiaryInfo(str(i), str(i), i, i)
        a.saveUserInfo(str(i), str(i), i, str(i))
    '''
    a.closeDb()
    #TestCase

db 파일 주소를 os.path.join(os.path.expanduser('~'), 'documents', 'Diary', 'Diary.db') 이렇게 설정한 이유는 exe로 만들어도 잘 작동하게 하기 위함이다.

 

if __name__ == "__main__"안에 들어있는 것은 테스트 코드이다.

 

다음은 Assistant.py이다.

from DbManager import DbManager 
import os
import arrow
import hashlib
import sqlite3

class WatchDiary:
    def readCorrectDiaryTxt(self, date):
        directory = os.path.join(os.path.expanduser('~'), 'documents', 'Diary', 'DiaryStorage', str(date) + '.txt')
        if os.path.isfile(directory):   
            with open(directory, 'r') as f:
                return f.read()
        else:
            return -1
    def readCorrectTodayThoughtsTxt(self, date):
        directory = os.path.join(os.path.expanduser('~'), 'documents', 'Diary', 'TodayThoughtsStorage', str(date) + '.txt')
        if os.path.isfile(directory):
            with open(directory, 'r') as f:
                return f.read()
        else:
            return -1
        

class WriteDiary:
    def saveDiaryTxt(self, date, content):
        directory = os.path.join(os.path.expanduser('~'), 'documents', 'Diary', 'DiaryStorage', str(date) + '.txt')
        with open(directory, 'w+t') as f:
            f.write(content)
        return f.closed
    def saveTodayThoughtsTxt(self, date,content):
        directory = os.path.join(os.path.expanduser('~'), 'documents', 'Diary', 'TodayThoughtsStorage', str(date) + '.txt')
        with open(directory, 'w+t') as f:
            f.write(content)
        return f.closed

class AccountManager:
    def __init__(self):
        self.DbManager = DbManager()

    def makeHash(self, inputText):
        inputText = inputText.encode()
        hashObject = hashlib.sha256()
        hashObject.update(inputText)
        hexDig = hashObject.hexdigest()
        return hexDig

    def logIn(self, id, pw):

        hexDig = self.makeHash(pw)
        userPw = self.DbManager.readUserPw(id)

        if userPw == (hexDig,): #userPw가 튜플임.
            return True
        else: 
            return False

    def registerUser(self, id, pw, sQuestionNum, answer):
        pw = self.makeHash(pw)
        
        answer = self.makeHash(answer)
        self.DbManager.saveUserInfo(id = id, pw = pw, sQuestionNum = sQuestionNum, answer = answer)
        return True

    def deleteId(self, id):
        self.DbManager.deleteUserInfo(id)

    def findId(self, sQuestionNum, answer):
        answer = self.makeHash(answer)

        id = self.DbManager.readUserIdByQA(sQuestionNum, answer) 
        if len(id) == 1:
            id = id[0]
        else:
            return -1
        return id
        

    def resetPw(self, id):
        newPw = 'aXeYCQV'
        newPw = newPw.encode()
        hashObject = hashlib.sha256()
        hashObject.update(newPw)
        hexDig = hashObject.hexdigest()
        newPw = hexDig

        self.DbManager.updatePw(id, newPw)

class Setup:
    def __init__(self):
        if os.path.isdir(os.path.join(os.path.expanduser('~'), 'documents', 'Diary', 'DiaryStorage')):
            pass
        else:
            os.makedirs(os.path.join(os.path.expanduser('~'), 'documents', 'Diary', 'DiaryStorage'))
        
        if os.path.isdir(os.path.join(os.path.expanduser('~'), 'documents', 'Diary', 'TodayThoughtsStorage')):
            pass
        else:
            os.makedirs(os.path.join(os.path.expanduser('~'), 'documents', 'Diary', 'TodayThoughtsStorage'))

        if os.path.isfile(os.path.join(os.path.expanduser('~'), 'documents', 'Diary', 'Diary.db')):
            pass
        else:
            conn = sqlite3.connect(os.path.join(os.path.expanduser('~'), 'documents', 'Diary', 'Diary.db'))
            c = conn.cursor()
            c.execute('''CREATE TABLE "Diary" ("Date"
                TEXT NOT NULL,"Time"
                TEXT NOT NULL,"todayFeel"
                INTEGER NOT NULL,"TodayThoughtsCount"
                TEXT,"Writer"
                TEXT NOT NULL,PRIMARY KEY("Date"));''')
            c.execute('''CREATE TABLE "User" (
    	        "ID"	TEXT NOT NULL UNIQUE,
	            "PW"	TEXT NOT NULL,
	            "sQuestionNum"	INTEGER NOT NULL,
	            "answer"	TEXT NOT NULL,
        	    PRIMARY KEY("ID"));''')

if __name__ == "__main__":
    #일기 저장 버튼 누르면 일기는 txt파일로, 나머지는 db에 저장
    #일기보기 누르면 DB로 정렬하고 txt파일 따로 읽기
    #if click view diary Button-> readCorrectDiaryTxt(DbManager.Read(date))
    z = Setup()
    a = WatchDiary()
    b = WriteDiary()
    c = AccountManager()
    d = c.findId(3,'qwerty')
    print(d)
    c.registerUser('asdfgg', 'asdfgzxdcvz1', 3, 'a')
    b.saveDiaryTxt(arrow.now().date(), input("일기입력"))
    f = a.readCorrectDiaryTxt(arrow.now().date())
    print(f)

마찬가지로 if __name__ == "__main__"안에 들어있는 것은 테스트 코드이다.

 

inputText = inputText.encode()

hashObject = hashlib.sha256()

hashObject.update(inputText)

hexDig = hashObject.hexdigest()

inputText = hexDig

이 코드는 sha-256을 이용해서 암호화는 코드다.

 

마지막으로 Main.py이다.

# -*- coding: utf-8 -*-

###########################################################################
## Python code generated with wxFormBuilder (version Oct 26 2018)
## http://www.wxformbuilder.org/
##
## PLEASE DO *NOT* EDIT THIS FILE!
###########################################################################

import wx
import wx.xrc
from DbManager import DbManager
from Assistant import WatchDiary, WriteDiary, AccountManager, Setup
import arrow
import re
import sys
#주의: 레이아웃 코드 복붙할때 기존 코드 안날라가게 조심!
###########################################################################
## Class StartMenu
###########################################################################

class StartMenu ( wx.Frame ):

	def __init__( self, parent, size ):
		wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(500, 300), style = wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX) )

		self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )

		bSizer1 = wx.BoxSizer( wx.VERTICAL )

		self.login_button = wx.Button( self, wx.ID_ANY, u"Login", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer1.Add( self.login_button, 1, wx.ALL|wx.EXPAND, 5 )

		self.signup_button = wx.Button( self, wx.ID_ANY, u"회원가입", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer1.Add( self.signup_button, 1, wx.ALL|wx.EXPAND, 5 )


		self.SetSizer( bSizer1 )
		self.Layout()

		self.Centre( wx.BOTH )

		# Connect Events
		self.Bind( wx.EVT_CLOSE, self.onClose )
		self.login_button.Bind( wx.EVT_BUTTON, self.loginButtonClicked )
		self.signup_button.Bind( wx.EVT_BUTTON, self.signUpButtonClicked )

	def __del__( self ):
		pass


	# Virtual event handlers, overide them in your derived class
	def onClose(self, event):
		a = DbManager()
		a.closeDb()
		self.Destroy()
		sys.exit()
		

	def loginButtonClicked( self, event ):
		if self.IsMaximized():
			frameSize = 'max'
		else:
			frameSize = self.GetSize()
		frame1 = LoginMenu(parent=None, size=frameSize)
		frame1.Show(True)
		self.Show(False)
		

	def signUpButtonClicked( self, event ):
		if self.IsMaximized():
			frameSize = 'max'
		else:
			frameSize = self.GetSize()
		frame1 = SignUpMenu(parent = None, size=frameSize)
		frame1.Show(True)
		self.Show(False)
		

###########################################################################
## Class DiaryMainMenu
###########################################################################

class DiaryMainMenu ( wx.Frame ):

	def __init__( self, parent, size, userId):
		wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(500, 300), style = wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX) )

		self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )

		bSizer1 = wx.BoxSizer( wx.VERTICAL )

		self.watch_button = wx.Button( self, wx.ID_ANY, u"일기보기", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer1.Add( self.watch_button, 1, wx.ALL|wx.EXPAND, 5 )

		self.write_button = wx.Button( self, wx.ID_ANY, u"일기쓰기", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer1.Add( self.write_button, 1, wx.ALL|wx.EXPAND, 5 )


		self.SetSizer( bSizer1 )
		self.Layout()

		self.Centre( wx.BOTH )

		# Connect Events
		self.Bind( wx.EVT_CLOSE, self.onClose )
		self.watch_button.Bind( wx.EVT_BUTTON, self.watchButtonClicked )
		self.write_button.Bind( wx.EVT_BUTTON, self.writeButtonClicked )

		self.DbManager = DbManager()
		self.userId = userId

	def __del__( self ):
		pass


	# Virtual event handlers, overide them in your derived class
	def onClose( self, event ):
		self.DbManager.closeDb()
		self.Destroy()
		sys.exit()
		

	def watchButtonClicked( self, event ):
		if self.IsMaximized():
			frameSize = 'max'
		else:
			frameSize = self.GetSize()
		frame1 = WatchDiaryMenu(parent=None, size=frameSize, userId=self.userId)
		frame1.Show(True)
		self.Show(False)
		

	def writeButtonClicked( self, event ):
		if self.IsMaximized():
			frameSize = 'max'
		else:
			frameSize = self.GetSize()
		frame1 = WriteDiaryMenu(parent=None, mode= 'w', size=frameSize, userId=self.userId)
		frame1.Show(True)
		self.Show(False)
		

###########################################################################
## Class LoginMenu
###########################################################################

class LoginMenu ( wx.Frame ):

	def __init__( self, parent, size ):
		wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(300,300), style = wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX) )

		self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )

		bSizer2 = wx.BoxSizer( wx.VERTICAL )

		self.go_back_button = wx.Button( self, wx.ID_ANY, u"뒤로가기", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer2.Add( self.go_back_button, 0, wx.ALL, 5 )

		self.m_panel7 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer19 = wx.BoxSizer( wx.VERTICAL )

		self.id_input_box = wx.TextCtrl( self.m_panel7, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer19.Add( self.id_input_box, 0, wx.ALL, 5 )

		self.pw_input_box = wx.TextCtrl( self.m_panel7, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_PASSWORD|wx.TE_PROCESS_ENTER )
		bSizer19.Add( self.pw_input_box, 0, wx.ALL, 5 )


		self.m_panel7.SetSizer( bSizer19 )
		self.m_panel7.Layout()
		bSizer19.Fit( self.m_panel7 )
		bSizer2.Add( self.m_panel7, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )

		self.login_button = wx.Button( self, wx.ID_ANY, u"로그인", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer2.Add( self.login_button, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )


		self.SetSizer( bSizer2 )
		self.Layout()

		self.Centre( wx.BOTH )

		# Connect Events
		self.Bind( wx.EVT_CLOSE, self.onClose )
		self.go_back_button.Bind( wx.EVT_BUTTON, self.goBackButtonClicked )
		self.pw_input_box.Bind( wx.EVT_TEXT_ENTER, self.pwInputFinished )
		self.login_button.Bind( wx.EVT_BUTTON, self.loginButtonClicked )

		self.DbManager = DbManager()
		self.accountManager = AccountManager()

	def __del__( self ):
		pass


	# Virtual event handlers, overide them in your derived class
	def onClose( self, event ):
		self.DbManager.closeDb()
		self.Destroy()
		sys.exit()

	def goBackButtonClicked( self, event ):
		if self.IsMaximized():
			frameSize = 'max'
		else:
			frameSize = self.GetSize()
		frame1 = StartMenu(parent=None, size=frameSize)
		frame1.Show(True)
		self.Show(False)

	def pwInputFinished( self, event ):
		self.loginButtonClicked(event = None)

	def loginButtonClicked( self, event ):
		id = self.id_input_box.GetValue()
		pw = self.pw_input_box.GetValue()

		pwFollowRule = True
		try:
			if re.findall('[a-zA-Z0-9]+', pw)[0] != pw: 
				pwFollowRule = False
		except:
			if len(re.findall('[^a-zA-Z0-9]+', pw)[0])>0:
				pwFollowRule = False
			else:
				raise BaseException

		idFollowRule = True
		try:
			if re.findall('[a-zA-Z0-9]+', id)[0] != id: 
				idFollowRule = False
		except:
			if len(re.findall('[^a-zA-Z0-9]+', id)[0])>0:
				idFollowRule = False
			else:
				raise BaseException
			
		if pwFollowRule and idFollowRule:	
			loginAccepted = self.accountManager.logIn(id, pw)
		else:
			loginAccepted = False
		
		if loginAccepted:
			if self.IsMaximized():
				frameSize = 'max'
			else:
				frameSize = self.GetSize()
			frame1 = DiaryMainMenu(parent=None, size=frameSize, userId= self.id_input_box.GetValue())
			frame1.Show(True)
			self.Show(False)
		else:
			wx.MessageBox("로그인 실패!")

		return loginAccepted


###########################################################################
## Class SignUpMenu
###########################################################################

class SignUpMenu ( wx.Frame ):

	def __init__( self, parent, size ):
		wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(500, 300), style = wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX) )

		self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )

		gSizer2 = wx.GridSizer( 0, 2, 0, 0 )

		bSizer7 = wx.BoxSizer( wx.VERTICAL )

		self.m_panel6 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
		gSizer7 = wx.GridSizer( 0, 2, 0, 0 )

		bSizer17 = wx.BoxSizer( wx.VERTICAL )

		self.goBackButton = wx.Button( self.m_panel6, wx.ID_ANY, u"뒤로가기", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer17.Add( self.goBackButton, 0, wx.ALL, 5 )


		gSizer7.Add( bSizer17, 1, wx.EXPAND, 5 )

		bSizer18 = wx.BoxSizer( wx.VERTICAL )

		self.id_confirm_button = wx.Button( self.m_panel6, wx.ID_ANY, u"ID중복확인", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer18.Add( self.id_confirm_button, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )


		gSizer7.Add( bSizer18, 1, wx.EXPAND, 5 )


		self.m_panel6.SetSizer( gSizer7 )
		self.m_panel6.Layout()
		gSizer7.Fit( self.m_panel6 )
		bSizer7.Add( self.m_panel6, 0, wx.ALL|wx.EXPAND, 5 )

		self.m_panel5 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
		gSizer5 = wx.GridSizer( 0, 2, 0, 0 )

		bSizer13 = wx.BoxSizer( wx.VERTICAL )

		self.id_input_text = wx.StaticText( self.m_panel5, wx.ID_ANY, u"ID", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.id_input_text.Wrap( -1 )

		bSizer13.Add( self.id_input_text, 0, wx.ALL|wx.EXPAND, 5 )

		self.id_input_box = wx.TextCtrl( self.m_panel5, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer13.Add( self.id_input_box, 0, wx.ALL|wx.EXPAND, 5 )

		self.pw_input_text = wx.StaticText( self.m_panel5, wx.ID_ANY, u"비밀번호", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.pw_input_text.Wrap( -1 )

		bSizer13.Add( self.pw_input_text, 0, wx.ALL|wx.EXPAND, 5 )

		self.pw_input_box = wx.TextCtrl( self.m_panel5, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_PASSWORD )
		bSizer13.Add( self.pw_input_box, 0, wx.ALL|wx.EXPAND, 5 )

		self.pw_re_input_text = wx.StaticText( self.m_panel5, wx.ID_ANY, u"비밀번호 재입력", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.pw_re_input_text.Wrap( -1 )

		bSizer13.Add( self.pw_re_input_text, 0, wx.ALL|wx.EXPAND, 5 )

		self.pw_re_input_box = wx.TextCtrl( self.m_panel5, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_PASSWORD )
		bSizer13.Add( self.pw_re_input_box, 0, wx.ALL|wx.EXPAND, 5 )


		gSizer5.Add( bSizer13, 1, wx.EXPAND, 5 )

		bSizer15 = wx.BoxSizer( wx.VERTICAL )

		self.pw_check_text = wx.StaticText( self.m_panel5, wx.ID_ANY, u"id,비밀번호 둘다\n영어 대소문자, \n숫자만 가능\n\n비밀번호는\n10자 이상\n영어,숫자 필수", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.pw_check_text.Wrap( -1 )

		bSizer15.Add( self.pw_check_text, 1, wx.ALL|wx.EXPAND, 5 )

		self.pw_confirm_img = wx.StaticBitmap( self.m_panel5, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer15.Add( self.pw_confirm_img, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )


		bSizer15.Add( ( 0, 0), 1, wx.EXPAND, 5 )


		gSizer5.Add( bSizer15, 1, wx.EXPAND, 5 )


		self.m_panel5.SetSizer( gSizer5 )
		self.m_panel5.Layout()
		gSizer5.Fit( self.m_panel5 )
		bSizer7.Add( self.m_panel5, 1, wx.EXPAND |wx.ALL, 5 )

		self.re_pw_correct_text = wx.StaticText( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		self.re_pw_correct_text.Wrap( -1 )

		bSizer7.Add( self.re_pw_correct_text, 0, wx.ALL, 5 )


		gSizer2.Add( bSizer7, 1, wx.EXPAND|wx.RIGHT, 5 )

		bSizer8 = wx.BoxSizer( wx.VERTICAL )

		self.account_repair_question_text = wx.StaticText( self, wx.ID_ANY, u"보안질문", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.account_repair_question_text.Wrap( -1 )

		bSizer8.Add( self.account_repair_question_text, 0, wx.ALL|wx.EXPAND, 5 )

		account_repair_question_choiceChoices = [ u"가장 아끼는 물건은?", u"가장 좋아했던 선생님 성함은?", u"가장 감명깊게 읽은 책은?", u"가장 어려웠던 책은?" ]
		self.account_repair_question_choice = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, account_repair_question_choiceChoices, 0 )
		self.account_repair_question_choice.SetSelection( 0 )
		bSizer8.Add( self.account_repair_question_choice, 0, wx.ALL|wx.EXPAND, 5 )

		self.answer_text = wx.StaticText( self, wx.ID_ANY, u"답변", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.answer_text.Wrap( -1 )

		bSizer8.Add( self.answer_text, 0, wx.ALL|wx.EXPAND, 5 )

		self.answer_input_box = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer8.Add( self.answer_input_box, 0, wx.ALL|wx.EXPAND, 5 )

		self.sign_up_button = wx.Button( self, wx.ID_ANY, u"회원가입", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer8.Add( self.sign_up_button, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )


		gSizer2.Add( bSizer8, 1, wx.EXPAND, 5 )


		self.SetSizer( gSizer2 )
		self.Layout()

		self.Centre( wx.BOTH )

		# Connect Events
		self.Bind( wx.EVT_CLOSE, self.onClose )
		self.goBackButton.Bind( wx.EVT_BUTTON, self.goBackButtonClicked )
		self.id_confirm_button.Bind( wx.EVT_BUTTON, self.idConfirmButtonClicked )
		self.id_input_box.Bind(wx.EVT_TEXT, self.textInputedOnId)
		self.pw_input_box.Bind( wx.EVT_TEXT, self.textInputedOnPw )
		self.pw_re_input_box.Bind( wx.EVT_TEXT, self.textInputedOnRePw )
		self.account_repair_question_choice.Bind( wx.EVT_CHOICE, self.choiced )
		self.sign_up_button.Bind( wx.EVT_BUTTON, self.signUpButtonClicked )

		self.accountManager = AccountManager()
		self.sQuestionNum = 0
		self.dbManager = DbManager()
		self.correctSymbolPng = wx.Image('tick.png', wx.BITMAP_TYPE_ANY)
		self.correctSymbolPng.Rescale(32,32)
		self.correctSymbolPng = self.correctSymbolPng.ConvertToBitmap()
		self.incorrectSymbolPng = wx.Image('close.png', wx.BITMAP_TYPE_ANY)
		self.incorrectSymbolPng.Rescale(32,32)
		self.incorrectSymbolPng = self.incorrectSymbolPng.ConvertToBitmap()
		self.pw_confirm_img.SetBitmap(self.incorrectSymbolPng)
		self.idFlag = -1

	def __del__( self ):
		pass

		
	# Virtual event handlers, overide them in your derived class

	def onClose( self, event ):
		self.dbManager.closeDb()
		self.Destroy()
		sys.exit()
		

	def goBackButtonClicked( self, event ):
		if self.IsMaximized():
			frameSize = 'max'
		else:
			frameSize = self.GetSize()
		frame1 = StartMenu(parent=None, size=frameSize)
		frame1.Show(True)
		self.Show(False)
		
	
	def idConfirmButtonClicked( self, event ):
		allId = self.dbManager.readAllId()
		id = (self.id_input_box.GetValue(),)
		self.idFlag = False
		if not(id in allId):
			self.idFlag = True
		if self.idFlag:
			wx.MessageBox(f"'{id[0]}': 사용가능한 아이디 입니다.")
		else:
			wx.MessageBox(f"'{id[0]}': 사용불가능한 아이디 입니다.")

	def textInputedOnId(self, event):
		self.idFlag = -1
		

	def textInputedOnPw( self, event ):
		pw = self.pw_input_box.GetValue()

		self.pwFollowRule = True
		if len(pw)<9:
			self.pwFollowRule = False
		elif re.findall('[a-zA-Z0-9]+', pw)[0] != pw:#re에서 영어, 숫자만 찾기. 만약 다른 문자가 있다면 중간에 끊김 -> 본래 문자열과 달라짐 -> 구별 가능.
			self.pwFollowRule = False
		elif len(re.findall('[a-zA-Z]', pw)) == 0:
			self.pwFollowRule = False
		elif len(re.findall('\d', pw)) == 0:
			self.pwFollowRule = False

		if self.pwFollowRule:
			self.pw_confirm_img.SetBitmap(self.correctSymbolPng)
		else:
			self.pw_confirm_img.SetBitmap(self.incorrectSymbolPng)
		

	def textInputedOnRePw( self, event ):
		self.pwFlag = self.pw_input_box.GetValue() == self.pw_re_input_box.GetValue()
		if self.pwFlag:
			self.re_pw_correct_text.SetLabel("비밀번호가 일치합니다!")
		else:
			self.re_pw_correct_text.SetLabel("비밀번호가 일치하지 않습니다.")
		

	def choiced( self, event ):
		self.sQuestionNum = self.account_repair_question_choice.GetSelection()
		print(self.sQuestionNum)
		return self.sQuestionNum
		

	def signUpButtonClicked( self, event ):
		if self.idFlag == -1:
			wx.MessageBox("아이디 중복확인 해주세요!")
		try:
			if re.findall('[a-zA-Z0-9]+', self.id_input_box.GetValue())[0] != self.id_input_box.GetValue(): 
				wx.MessageBox("이 아이디는 사용할 수 없습니다(영어 대소문자,숫자로 이루어지지 않음)")
				self.idFlag = False
		except:
			if len(re.findall('[^a-zA-Z0-9]+', self.id_input_box.GetValue())[0])>0:
				wx.MessageBox("이 아이디는 사용할 수 없습니다(영어 대소문자,숫자로 이루어지지 않음)")
				self.idFlag = False
			else:
				raise BaseException
		if not(self.id_input_box.GetValue() == None and self.pw_input_box.GetValue() == None and self.answer_input_box.GetValue() == None):
			if self.idFlag == True and self.pwFlag ==True and self.pwFollowRule == True:
				loginSuccess = self.accountManager.registerUser(self.id_input_box.GetValue(), self.pw_input_box.GetValue(), self.sQuestionNum, self.answer_input_box.GetValue())
				if loginSuccess:
					wx.MessageBox(f"회원가입 성공! 아이디는 '{self.id_input_box.GetValue()}'")
					if self.IsMaximized():
						frameSize = 'max'
					else:
						frameSize = self.GetSize()
					frame1 = DiaryMainMenu(parent=None, size=frameSize, userId=self.id_input_box.GetValue())
					frame1.Show(True)
					self.Show(False)
				else:
					wx.MessageBox(f"회원가입 실패ㅜㅜ")
		else:
			wx.MessageBox('공란이 있으면 안됨')
		return self.id_input_box.GetValue(), self.pw_input_box.GetValue(), self.sQuestionNum, self.answer_input_box.GetValue()
		


###########################################################################
## Class WriteDiaryMenu
###########################################################################

class WriteDiaryMenu ( wx.Frame ):

	def __init__( self, parent, mode ,size, userId, diaryContent=None, todayFeel=5, todayThoughts = None):
		if size == 'max':
			wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(500,300), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
			self.Maximize()
		else:
			wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(size), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

		self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )

		gSizer3 = wx.GridSizer( 0, 2, 0, 0 )

		bSizer7 = wx.BoxSizer( wx.VERTICAL )

		self.go_back_button = wx.Button( self, wx.ID_ANY, u"뒤로가기", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer7.Add( self.go_back_button, 0, wx.ALL, 5 )

		if mode == "w":
			if diaryContent == None:
				self.diary_input_box = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE )
			else:
				self.diary_input_box = wx.TextCtrl( self, wx.ID_ANY, u"{0}".format(diaryContent), wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE )
		else:
			self.diary_input_box = wx.TextCtrl( self, wx.ID_ANY, u'{0}'.format(diaryContent), wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE|wx.TE_READONLY )
		bSizer7.Add( self.diary_input_box, 1, wx.ALL|wx.EXPAND, 5 )


		gSizer3.Add( bSizer7, 1, wx.EXPAND, 5 )

		bSizer8 = wx.BoxSizer( wx.VERTICAL )

		self.m_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
		bSizer9 = wx.BoxSizer( wx.VERTICAL )

		self.today_feel_text = wx.StaticText( self.m_panel1, wx.ID_ANY, u"오늘 기분1/5", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.today_feel_text.Wrap( -1 )

		bSizer9.Add( self.today_feel_text, 0, wx.ALL, 5 )
		if mode == 'w':
			self.today_feel_slider = wx.Slider( self.m_panel1, wx.ID_ANY, todayFeel, 1, 5, wx.DefaultPosition, wx.DefaultSize, wx.SL_HORIZONTAL|wx.SL_SELRANGE|wx.SL_VALUE_LABEL )
			bSizer9.Add( self.today_feel_slider, 0, wx.ALL|wx.EXPAND, 5 )
		else:
			self.today_feel_text = wx.StaticText( self.m_panel1, wx.ID_ANY, u"{0}".format(todayFeel), wx.DefaultPosition, wx.DefaultSize, 0 )
			self.today_feel_text.Wrap( -1 )
			bSizer9.Add( self.today_feel_text, 0, wx.ALL, 5 )

		self.m_panel1.SetSizer( bSizer9 )
		self.m_panel1.Layout()
		bSizer9.Fit( self.m_panel1 )
		bSizer8.Add( self.m_panel1, 0, wx.EXPAND |wx.ALL, 5 )

		self.m_panel2 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
		bSizer10 = wx.BoxSizer( wx.VERTICAL )

		self.today_thoughts_text = wx.StaticText( self.m_panel2, wx.ID_ANY, u"오늘 생각한것", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.today_thoughts_text.Wrap( -1 )

		bSizer10.Add( self.today_thoughts_text, 0, wx.ALL, 5 )
		
		if mode == 'w':
			if todayThoughts == None:
				self.today_thoughts_input_box = wx.TextCtrl( self.m_panel2, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE )
			else:
				self.today_thoughts_input_box = wx.TextCtrl( self.m_panel2, wx.ID_ANY, u"{0}".format(todayThoughts), wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE )
		else: 
			self.today_thoughts_input_box = wx.TextCtrl( self.m_panel2, wx.ID_ANY, u"{0}".format(todayThoughts), wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE|wx.TE_READONLY )
		bSizer10.Add( self.today_thoughts_input_box, 1, wx.ALL|wx.EXPAND, 5 )


		self.m_panel2.SetSizer( bSizer10 )
		self.m_panel2.Layout()
		bSizer10.Fit( self.m_panel2 )
		bSizer8.Add( self.m_panel2, 1, wx.EXPAND |wx.ALL, 5 )

		if mode == 'w':
			self.save_diary_button = wx.Button( self, wx.ID_ANY, u"일기 저장", wx.DefaultPosition, wx.DefaultSize, 0 )
			bSizer8.Add( self.save_diary_button, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
			self.save_diary_button.Bind( wx.EVT_BUTTON, self.saveButtonClicked )


		gSizer3.Add( bSizer8, 1, wx.EXPAND, 5 )


		self.SetSizer( gSizer3 )
		self.Layout()

		self.Centre( wx.BOTH )

		# Connect Events
		self.Bind( wx.EVT_CLOSE, self.onClose )
		self.go_back_button.Bind( wx.EVT_BUTTON, self.goBackButtonClicked )
		

		self.dbManager = DbManager()
		self.WriteDiary = WriteDiary()
		self.userId = userId

	def __del__( self ):
		pass


	# Virtual event handlers, overide them in your derived class
	def onClose( self, event ):
		self.dbManager.closeDb()
		self.Destroy()
		sys.exit()
		

	def goBackButtonClicked( self, event ):
		if self.IsMaximized():
			frameSize = 'max'
		else:
			frameSize = self.GetSize()
		frame1 = DiaryMainMenu(parent=None, size=frameSize, userId = self.userId)
		frame1.Show(True)
		self.Show(False)
		

	def saveButtonClicked( self, event ):
		self.WriteDiary.saveDiaryTxt(arrow.now().date(), self.diary_input_box.GetValue())
		self.WriteDiary.saveTodayThoughtsTxt(arrow.now().date(), self.today_thoughts_input_box.GetValue())
		self.dbManager.saveDiaryInfo(arrow.now().date(), str(arrow.now().time())[:5], self.today_feel_slider.GetValue(), self.today_thoughts_input_box.GetValue(), self.userId)
		wx.MessageBox("일기 저장 성공!")

		if self.IsMaximized():
			frameSize = 'max'
		else:
			frameSize = self.GetSize()
		frame1 = DiaryMainMenu(parent=None, size=frameSize, userId = self.userId)
		frame1.Show(True)
		self.Show(False)
		


###########################################################################
## Class WatchDiaryMenu
###########################################################################

class WatchDiaryMenu ( wx.Frame ):

	def __init__( self, parent, size ,userId):
		if size == 'max':
			wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(500,300), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
			self.Maximize()
		else:
			wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(size), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

		self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
		bSizer12 = wx.BoxSizer( wx.VERTICAL )

		self.go_back_button = wx.Button( self, wx.ID_ANY, u"뒤로가기", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer12.Add( self.go_back_button, 0, wx.ALL, 5 )

		self.m_panel81 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
		gbSizer31 = wx.GridBagSizer( 0, 0 )
		gbSizer31.SetFlexibleDirection( wx.BOTH )
		gbSizer31.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )

		self.range_text = wx.StaticText( self.m_panel81, wx.ID_ANY, u"범위", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.range_text.Wrap( -1 )

		gbSizer31.Add( self.range_text, wx.GBPosition( 0, 0 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )

		range_choiceChoices = [ u"전체", u"선택" ]
		self.range_choice = wx.Choice( self.m_panel81, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, range_choiceChoices, 0 )
		self.range_choice.SetSelection( 0 )
		gbSizer31.Add( self.range_choice, wx.GBPosition( 0, 1 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )

		self.feel_text = wx.StaticText( self.m_panel81, wx.ID_ANY, u"기분", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.feel_text.Wrap( -1 )

		gbSizer31.Add( self.feel_text, wx.GBPosition( 0, 2 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )

		feel_range_choiceChoices = [ u"전체", u"선택" ]
		self.feel_range_choice = wx.Choice( self.m_panel81, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, feel_range_choiceChoices, 0 )
		self.feel_range_choice.SetSelection( 0 )
		gbSizer31.Add( self.feel_range_choice, wx.GBPosition( 0, 3 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )

		self.thoughts_count_text = wx.StaticText( self.m_panel81, wx.ID_ANY, u"생각개수", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.thoughts_count_text.Wrap( -1 )

		gbSizer31.Add( self.thoughts_count_text, wx.GBPosition( 0, 4 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )

		feel_range_choice1Choices = [ u"전체", u"선택" ]
		self.feel_range_choice1 = wx.Choice( self.m_panel81, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, feel_range_choice1Choices, 0 )
		self.feel_range_choice1.SetSelection( 0 )
		gbSizer31.Add( self.feel_range_choice1, wx.GBPosition( 0, 5 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )

		self.search_button = wx.Button( self.m_panel81, wx.ID_ANY, u"검색", wx.DefaultPosition, wx.DefaultSize, 0 )
		gbSizer31.Add( self.search_button, wx.GBPosition( 0, 6 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )


		self.m_panel81.SetSizer( gbSizer31 )
		self.m_panel81.Layout()
		gbSizer31.Fit( self.m_panel81 )
		bSizer12.Add( self.m_panel81, 0, wx.ALL|wx.EXPAND, 5 )

		self.m_scrolledWindow2 = wx.ScrolledWindow( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.HSCROLL|wx.VSCROLL )
		self.m_scrolledWindow2.SetScrollRate( 5, 5 )
		bSizer22 = wx.BoxSizer( wx.VERTICAL )

		self.starPng = wx.Image('star.png', wx.BITMAP_TYPE_ANY)
		frameSizeX, frameSizeY = self.GetSize()
		self.starPng.Rescale(16,16)
		self.starPng = self.starPng.ConvertToBitmap()
		del frameSizeX, frameSizeY
		
		self.DbManager = DbManager()
		self.userId = userId

		diary = self.DbManager.findDiaryWithCondition(startDate='1970-01-01', finishDate='2099-01-01', startFeelRange=1, finishFeelRange=5, thoughtsStartRange=0, thoughtsFinishRange=100, userId=self.userId)
		for i in range(len(diary)):
			date = diary[i][0]
			time = diary[i][1]
			todayFeel = diary[i][2]
			todayThoughtsCount = diary[i][3]

			diaryPanel = self.makeDiaryPanel(date, time, todayFeel, todayThoughtsCount, len(diary), self.m_scrolledWindow2)
			bSizer22.Add( diaryPanel, 1, wx.EXPAND |wx.ALL, 5 )


		self.m_scrolledWindow2.SetSizer( bSizer22 )
		self.m_scrolledWindow2.Layout()
		bSizer22.Fit( self.m_scrolledWindow2 )
		bSizer12.Add( self.m_scrolledWindow2, 1, wx.EXPAND |wx.ALL, 5 )


		self.SetSizer( bSizer12 )
		self.Layout()

		self.Centre( wx.BOTH )

		

		# Connect Events
		self.Bind( wx.EVT_CLOSE, self.onClose )
		self.range_choice.Bind( wx.EVT_CHOICE, self.rangeChoiced )
		self.feel_range_choice.Bind( wx.EVT_CHOICE, self.feelRangeChoiced )
		self.feel_range_choice1.Bind( wx.EVT_CHOICE, self.thoughtsRangeChoiced )
		self.search_button.Bind( wx.EVT_BUTTON, self.searchButtonClicked )
		self.go_back_button.Bind( wx.EVT_BUTTON, self.goBackButtonClicked)

	def __del__( self ):
		pass

	def makeDiaryPanel(self, date, time, star, thoughtsCount, diaryCount, m_scrolledWindow2):
		m_panel8 = wx.Panel( m_scrolledWindow2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
		gbSizer3 = wx.GridBagSizer( 0, 0 )
		gbSizer3.SetFlexibleDirection( wx.BOTH )
		gbSizer3.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )

		date_text = wx.StaticText( m_panel8, wx.ID_ANY, u'{0}'.format(date), wx.DefaultPosition, wx.DefaultSize, 0 )
		date_text.Wrap( -1 )

		gbSizer3.Add( date_text, wx.GBPosition( 0, 0 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )

		time_text = wx.StaticText( m_panel8, wx.ID_ANY, u"{0}".format(time), wx.DefaultPosition, wx.DefaultSize, 0 )
		time_text.Wrap( -1 )

		gbSizer3.Add( time_text, wx.GBPosition( 0, 2 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )

		thoughts_count = wx.StaticText( m_panel8, wx.ID_ANY, u"{0}".format(thoughtsCount), wx.DefaultPosition, wx.DefaultSize, 0 )
		thoughts_count.Wrap( -1 )

		gbSizer3.Add( thoughts_count, wx.GBPosition( 0, 3 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )

		diary_show_button = wx.Button( m_panel8, wx.ID_ANY, u"일기보기", wx.DefaultPosition, wx.DefaultSize, 0 )
		gbSizer3.Add( diary_show_button, wx.GBPosition( 0, 5 ), wx.GBSpan( 1, 1 ), wx.ALL, 5 )

		m_panel18 = wx.Panel( m_panel8, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
		gbSizer4 = wx.GridBagSizer( 0, 0 )
		gbSizer4.SetFlexibleDirection( wx.BOTH )
		gbSizer4.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )

		for i in range(int(star)):
			star = wx.StaticBitmap( m_panel18, wx.ID_ANY, self.starPng, wx.DefaultPosition, wx.DefaultSize, 0 )
			gbSizer4.Add(star, wx.GBPosition(0,i), wx.GBSpan( 1, 1 ), wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5)

		m_panel18.SetSizer( gbSizer4 )
		m_panel18.Layout()
		gbSizer4.Fit( m_panel18 )
		gbSizer3.Add( m_panel18, wx.GBPosition( 0, 4 ), wx.GBSpan( 1, 1 ), wx.EXPAND |wx.ALL, 5 )

		m_panel8.SetSizer( gbSizer3 )
		m_panel8.Layout()
		gbSizer3.Fit( m_panel8 )

		diary_show_button.Bind( wx.EVT_BUTTON, lambda event: self.diaryShowButtonClicked(event, date))
		return m_panel8
		
		
	# Virtual event handlers, overide them in your derived class
	def onClose( self, event ):
		self.DbManager.closeDb()
		self.Destroy()
		sys.exit()

	def rangeChoiced( self, event ):
		event.Skip()

	def feelRangeChoiced( self, event ):
		event.Skip()

	def thoughtsRangeChoiced( self, event ):
		event.Skip()

	def searchButtonClicked( self, event ):
		event.Skip()

	def goBackButtonClicked(self, event):
		if self.IsMaximized():
			frameSize = 'max'
		else:
			frameSize = self.GetSize()
		frame1 = DiaryMainMenu(parent=None, size=frameSize, userId = self.userId)
		frame1.Show(True)
		self.Show(False)

	def diaryShowButtonClicked( self, event, date ):
		watchDiary = WatchDiary()
		diaryContent = watchDiary.readCorrectDiaryTxt(date)
		todayThoughtsContent = watchDiary.readCorrectTodayThoughtsTxt(date)
		diaryInfo = self.DbManager.readDiaryInfo(date, self.userId)
		if self.IsMaximized():
			frameSize = 'max'
		else:
			frameSize = self.GetSize()
		if date == str(arrow.now().date()):
			frame1 = WriteDiaryMenu(parent=None, mode='w', size=frameSize, userId=self.userId, diaryContent=diaryContent, todayFeel=diaryInfo[2], todayThoughts=todayThoughtsContent)
		else:
			frame1 = WriteDiaryMenu(parent=None, mode='r', size=frameSize, userId=self.userId, diaryContent=diaryContent, todayFeel=diaryInfo[2], todayThoughts=todayThoughtsContent)
		frame1.Show(True)
		self.Show(False)

if __name__ == "__main__":
	a = Setup()
	app = wx.App()
	frame = StartMenu(parent = None, size=(500,300))
	frame.Show(True)
	app.MainLoop()

모든 클래스의 __init__안에 들어있는 것은 UI생성하는 코드다. 

그래서 실제 코드는 생각보다 길지 않다.

 

마지막 부분 makeDiaryPanel함수는 일기 보여주기의 한 패널을 만드는 코드다.

 

이게 한 패널

 

 

이미지들은 https://www.flaticon.com/ 에서 구했다.

 

처음에는 frame을 어떻게하면 전환할 수 있을까 고민했는데, 그냥 야매로 다른 frame을 보여주고, 지금 frame은 숨기는 방식으로 구현했다. 

 

이제 아이디, 비밀번호 찾기 기능 만들기, 일기 검색 기능(날짜, 기분, 오늘 한 생각으로) 만들기, 오늘 한 생각 부분 디자인 변경하기 가 목표이다.

https://github.com/arduinocc04/wxPythonDiary

 

Assistant.py
0.00MB
close.png
0.01MB
DbManager.py
0.00MB
Main.py
0.03MB
star.png
0.00MB
tick.png
0.00MB