껐다가 새로 시작할 때는 먼저 터미널을 통해 venv를 activate 시키기
source venv/Scripts/activate
1. 시계를 만들기 위해 clock 폴더 생성
# clock 폴더를 만들 경로에서 clock 폴더 생성 명령어 입력
$ mkdir clock
# clock 폴더로 경로를 이동하여 pynecone 프로젝트 생성
$ cd clock
$ pc init

2. 시계 코드 작성
from pcconfig import config
import pynecone as pc
from datetime import datetime
import pytz
import asyncio
class State(pc.State):
# 초기 시간을 표시할 zone
zone: str = "Asia/Seoul"
# 초기에 시계를 작동시킬지 여부를 False로
start: bool = False
# pytz 라이브러리를 통해 각 zone의 현재 시간을 얻어옴
# AM, PM으로 오전, 오후를 구분하기 위해 12로 나눈 나머지 값을 hour에 저장
@pc.var
def hour(self):
return datetime.now(pytz.timezone(self.zone)).hour % 12
@pc.var
def minute(self):
return datetime.now(pytz.timezone(self.zone)).minute
# 분과 초의 표시 형식은 "00"처럼 두 자리 형태
@pc.var
def minute_display(self):
return f"{self.minute:02}"
@pc.var
def second(self):
return datetime.now(pytz.timezone(self.zone)).second
@pc.var
def second_display(self):
return f"{self.second:02}"
# hour가 12보다 작으면 오전이므로 "AM", 12시부터는 오후이므로 "PM"
@pc.var
def meridiem(self):
if datetime.now(pytz.timezone(self.zone)).hour < 12:
return "AM"
else:
return "PM"
# 시계의 분침과 초침은 1분, 1초에 6도씩 움직이므로 각 분과 초에 6을 곱하여 정상에서 몇 도 떨어져있는지 계산
# 시계의 시침은 시계 한바퀴를 12에 나누어 돌아서 한 시간 당 30도씩 움직임
@pc.var
def minute_rotation(self):
minute = self.minute * 6 - 90
return f"rotate({minute}deg)"
@pc.var
def hour_rotation(self):
hour = self.hour * 30 - 90
return f"rotate({hour}deg)"
@pc.var
def second_rotation(self):
second = self.second * 6 - 90
return f"rotate({second}deg)"
# asyncio.sleep함수를 사용하여 1초의 지연을 발생시킨 후 tick을 보냄
# 시계 동작 버튼이 True일때만 tick을 보냄
async def tick(self):
if self.start:
await asyncio.sleep(1)
return self.tick
# 시계 동작 여부를 False, True로 바꾸는 스위치
# True일 때만 tick 함수를 실행
def flip_switch(self, start):
self.start = start
if self.start:
return self.tick
# 시침, 분침, 초침 설정
def current_hour(hour):
return pc.divider(
transform = hour,
width = "16em",
position = "absolute",
border_style = "solid",
border_width = "4px",
border_image = "linear-gradient(to right, rgb(250, 250, 250) 50%, black 100%) 0 0 100% 0",
z_index = 0,
)
def current_minute(minute):
return pc.divider(
transform = minute,
width = "18em",
position = "absolute",
border_style = "solid",
border_width = "4px",
border_image = "linear-gradient(to right, rgb(250, 250, 250) 50%, red 100%) 0 0 100% 0",
z_index = 0,
)
def current_second(second):
return pc.divider(
transform = second,
width = "20em",
position = "absolute",
border_style = "solid",
border_width = "4px",
border_image = "linear-gradient(to right, rgb(250, 250, 250) 50%, blue 100%) 0 0 100% 0",
z_index = 0,
)
# 메인 페이지
def clock():
# 화면 가운데
return pc.center(
# 수직으로
pc.vstack(
# 맨 위에 동그라미(시계) 생성
pc.circle(
# 동그라미 안에 작은 동그라미 생성
pc.circle(
width = "1em",
height = "1em",
border_width = "thick",
border_color = "#43464B",
z_index = 1,
),
# 시계 안에 시침, 분침, 초침 추가
current_minute(State.minute_rotation),
current_hour(State.hour_rotation),
current_second(State.second_rotation),
# 그 외 동그라미 스타일 설정
border_width = "thick",
border_color = "#43464B",
width = "25em",
height = "25em",
bg = "rgb(250, 250, 250)",
box_shadow = "dark-lg",
),
# 동그라미(시계) 다 만들고 그 아래에 시간 텍스트로 표시
# 텍스트는 수평으로 추가
pc.hstack(
pc.hstack(
# 부모 State 클래스에 접근할 수 있는 pc.heading
pc.heading(State.hour),
pc.heading(":"),
pc.heading(State.minute_display),
pc.heading(":"),
pc.heading(State.second_display),
pc.heading(State.meridiem),
border_width = "medium",
border_color = "#43464B",
border_radius = "2em",
padding_x = "2em",
bg = "white",
color = "#333",
),
# 시계 작동 여부 스위치도 시간 텍스트 옆에 추가
pc.switch(is_checked = State.start, on_change = State.flip_switch),
),
# 동그라미 밑에 시간 텍스트 밑에 select 박스 추가
pc.select(
# select 목록
[
"Asia/Seoul",
"Australia/Sydney",
"Europe/Paris",
"Europe/Moscow",
"US/Pacific",
"US/Eastern",
],
# 초기에 select 박스에 표시되는 텍스트
placeholder = "Select a time zone",
# select 값이 바뀌는 Event가 발생하면 작동하는 Event Handler
on_change = State.set_zone,
bg = "#white",
),
padding = "5em",
border_width = "medium",
border_color = "#43464B",
border_radius = "25px",
bg = "#ededed",
text_align = "center",
),
padding = "5em",
)
app = pc.App(state=State)
app.add_page(clock, title = "Clock")
app.compile()
3. 알게 된 점
1) State의 요소
- Basic Vars: 흔히 알고 있는 변수 / Event Handler에 의해서 변할 수 있는 값
- Computed Vars: 다른 변수들의 함수 / 직접 생성될 수 없고 다른 변수에 의해 파생됨
- Events: 앱 내에서 발생하여 Event Handler를 작동시키는 행동
- Event Hanlders: Event에 의해 반응하는 함수 / State 클래스에서 함수로 정의됨
'Python > pynecone' 카테고리의 다른 글
[pynecone] 02. pynecone으로 counter app 만들기 (0) | 2023.01.18 |
---|---|
[pynecone] 01. 설치 (0) | 2023.01.18 |