껐다가 새로 시작할 때는 먼저 터미널을 통해 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

pynecone 공식 사이트 첫 번째 예제 만들어보기

https://pynecone.io/docs/getting-started/introduction

 

1. counter app을 위한 새로운 폴더 만들기

 

2. counter 폴더에 pynecone 프로젝트 생성해주기

cd counter
pc init

  - 터미널에서 해당 명령어로 counter 폴더에 접근해준뒤 "pc init" 명령어로 pynecone 프로젝트 생성

  - counter 폴더 안에 메인 파일인 counter.py가 생성됨

 

3. counter.py 작성

  - 원래의 기본 코드는 다 지우고 counter app을 만들기 위해 기본 틀만 남김

from pcconfig import config
import pynecone as pc

# 각종 상태값을 정의하고 변경하기 위한 State 클래스
class State(pc.State):
    pass

# 앱의 메인
def index():
    return 

# 앱 인스턴스 생성
# 페이지 추가
# 컴파일
app = pc.App(state=State)
app.add_page(index)
app.compile()

 

  - pynecone 홈페이지의 코드 작성

from pcconfig import config
import pynecone as pc

# 각종 상태값을 정의하고 변경하기 위한 State 클래스
class State(pc.State):

    # 변수는 모두 State에서 정의
    count = 0

    def increment(self):
        self.count += 1
    
    def decrement(self):
        self.count -= 1

# 앱의 메인
def index():
    return pc.hstack(
            # 버튼을 클릭했을 때, State에서 정의한 decrement 함수가 실행
            pc.button("desc - 1", on_click = State.decrement, color_scheme = "red", border_radius = "1em"),
            # State에서 정의한 count 변수
            pc.text(State.count),
            # 버튼을 클릭했을 때, State에서 정의한 increment 함수가 실행
            pc.button("asc + 1", on_click = State.increment, color_scheme = "green", border_radius = "1em"),
        )
    )

# 앱 인스턴스 생성
# 페이지 추가
# 컴파일
app = pc.App(state=State)
app.add_page(index)
app.compile()

 

  - 해당 페이지로 실행(pc run을 통해 한 번만 연결해두면 ctrl + s로 저장만 하면 자동으로 서버 재시작됨)

 

  - 추가로 페이지의 중앙에 놓기, ±10 버튼 만들기 연습

from pcconfig import config
import pynecone as pc

# 각종 상태값을 정의하고 변경하기 위한 State 클래스
class State(pc.State):

    # 변수는 모두 State에서 정의
    count = 0

    def increment(self):
        self.count += 1

    def increment_10(self):
        self.count += 10   
    
    def decrement(self):
        self.count -= 1

    def decrement_10(self):
        self.count -= 10

# 앱의 본체에 해당하는 함수(index)
def index():
    return pc.center(
        pc.hstack(
            pc.button("desc - 10", on_click = State.decrement_10, color_scheme = "red", border_radius = "1em"),
            pc.button("desc - 1", on_click = State.decrement, color_scheme = "red", border_radius = "1em"),
            pc.text(State.count),
            pc.button("asc + 1", on_click = State.increment, color_scheme = "green", border_radius = "1em"),
            pc.button("asc + 10", on_click = State.increment_10, color_scheme = "green", border_radius = "1em"),
        ), padding = "50px"
    )

# 앱의 인스턴스 생성
# 페이지 추가
# 컴파일
app = pc.App(state=State)
app.add_page(index)
app.compile()

'Python > pynecone' 카테고리의 다른 글

[pynecone] 03. pynecone으로 시계 만들기  (0) 2023.01.19
[pynecone] 01. 설치  (0) 2023.01.18

1. 터미널에 "pip install pynecone-io"를 입력하여 설치

2. node js 설치

https://nodejs.org/ko/

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

 

3. pynecone을 연습해볼 폴더 생성

  - 커맨드 창에 다음 코드를 입력하여 가상환경 생성(git bash 이용)

# my_app이라는 폴더 생성
$ mkdir my_app
# 생성한 my_app 폴더로 현재 위치 이동
$ cd my_app
# 파이썬 가상환경 생성
$ python -m venv venv
# 가상환경 활성화
$ source venv/Scripts/activate

  - pynecone 설치, node js 설치

pip install pynecone-io
# node js를 가상환경 별로 사용할 수 있게 해주는 패키지
pip install nodeenv
# 현재 가상환경에 독립된 nodejs 환경 추가
nodeenv -p
# nodejs 버전 잘 나오는지 확인
node -v

  - 여기까지 만들어진 폴더

 

  - 터미널에 "pc init" 명령어로 pynecone 프로젝트를 초기화 시켜주면 다음과 같은 폴더 구조가 생성됨

pc init

  - 여기서 my_app.py가 메인 실행 파일

# my_app.py
"""Welcome to Pynecone! This file outlines the steps to create a basic app."""
from pcconfig import config

import pynecone as pc

docs_url = "https://pynecone.io/docs/getting-started/introduction"
filename = f"{config.app_name}/{config.app_name}.py"


class State(pc.State):
    """The app state."""

    pass


def index():
    return pc.center(
        pc.vstack(
            pc.heading("Welcome to Pynecone!", font_size="2em"),
            pc.box("Get started by editing ", pc.code(filename, font_size="1em")),
            pc.link(
                "Check out our docs!",
                href=docs_url,
                border="0.1em solid",
                padding="0.5em",
                border_radius="0.5em",
                _hover={
                    "color": "rgb(107,99,246)",
                },
            ),
            spacing="1.5em",
            font_size="2em",
        ),
        padding_top="10%",
    )


# Add state and page to the app.
app = pc.App(state=State)
app.add_page(index)
app.compile()

 

  - 터미널에 "pc run" 명령어 실행하면 서버 열림

pc run

  - localhost:3000을 통해 접속(오류가 뜨기는 하지만 정상)

 

  - my_app.py 파일을 다음과 같이 변경하여 다시 "pc run"을 실행해보면 아래의 페이지가 정상적으로 출력됨

from pcconfig import config
import pynecone as pc

class State(pc.State):
   pass


def index():
    return pc.text("Hello World")

app = pc.App(state=State)
app.add_page(index)
app.compile()

+ Recent posts