본문 바로가기
REFLEX 튜토리얼

[pynecone] Dall-E 2 이미지 생성 앱 만들기③ #컴포넌트

by 일코 2023. 2. 16.

지난 포스팅에서는

우리 튜토리얼 프로젝트인 Dall-E 웹앱에 들어가는 구성요소,
즉 우리 앱을 구성할 컴포넌트 목록에 대해 알아보았습니다.

2023.02.15 - [pynecone 튜토리얼] - [pynecone] Dall-E 2 이미지 생성 앱 만들기②

 

[pynecone] Dall-E 2 이미지 생성 앱 만들기②

지난 포스팅에서는 openai.com Dall-E2의 API를 활용하여 이미지를 생성해보았습니다. (아직 본격적인 파인콘 앱을 만들지는 않았습니다.) 2023.02.15 - [pynecone 튜토리얼] - [pynecone] Dall-E 2 이미지 생성 앱

martinii.fun

 

이번 포스팅에서는
우리가 이 앱에서 다룰 컴포넌트에 대해
개략적으로만 알아봅시다.

코드에 출현하는 10개의 컴포넌트를 미리 순서대로 나열해보면
아래와 같습니다.

파인콘에 어떤 컴포넌트가 있는지, 어떤 컴포넌트가 없는지는
다소 많아 보이고, 익히는 데 시간이 걸리더라도
어느 정도는 윤곽을 알아두셔야 합니다.
기본적으로 무엇을 만들 수 있고, 없는지 한계를 명확히 알아야만
주도적으로 레이아웃을 짜고 디자인을 할 수 있으니까요.

참고로 파인콘의 기본제공 컴포넌트를 검색하실 때는 
https://pynecone.io/docs/library 를 사용하시면 편리합니다.

 

pc.center

내부의 컴포넌트를 중앙으로 정렬해주는 컨테이너의 한 종류입니다.
border 속성(border_radius, border_width)이나 
width, height 등을 임의로 설정할 수 있습니다.
이와 유사한 컴포넌트로는 pc.circle과 pc.square가 있는데,
이 둘은 pc.center로 구현 가능한 일종의 하위 컴포넌트입니다.

코드 예시

def index():
    return pc.square(
        pc.heading("DALL-E", font_size="1.5em"),
        width="100%",  # 브라우저 화면의 너비 100%를 전부 쓰겠다
        height="100vh",  # viewport-height의 100%를 전부 쓰겠다
        background="radial-gradient(circle at 22% 11%,rgba(62, 180, 137,.20),hsla(0,0%,100%,0) 19%),radial-gradient(circle at 82% 25%,rgba(33,150,243,.18),hsla(0,0%,100%,0) 35%),radial-gradient(circle at 25% 61%,rgba(250, 128, 114, .28),hsla(0,0%,100%,0) 55%)",
    )

구현화면

 

 

pc.vstack

pc.stack의 하위 컴포넌트로,
컴포넌트를 세로방향으로 차곡차곡 담아줍니다.

코드 예시

아래의 코드는
pc.heading, pc.input, pc.button 등 세 개의 컴포넌트를
세로로 쌓아줍니다.

def index():
    return pc.center(
        pc.vstack(
            pc.heading("DALL-E", font_size="1.5em"),
            pc.input(placeholder="Enter a prompt..", on_blur=State.set_prompt),
            pc.button("Generate Image", width="100%"),
            bg="white", padding="2em", shadow="lg", border_radius="lg"),
        width="100%", height="100vh", background="radial-gradient(circle at 22% 11%,rgba(62, 180, 137,.20),hsla(0,0%,100%,0) 19%),radial-gradient(circle at 82% 25%,rgba(33,150,243,.18),hsla(0,0%,100%,0) 35%),radial-gradient(circle at 25% 61%,rgba(250, 128, 114, .28),hsla(0,0%,100%,0) 55%)",
    )

구현화면

 

pc.heading

제목텍스트를 표시할 때 사용하는 컴포넌트로,
변경가능한 속성은 size, font_size, color 등이 있습니다.
size는 "4xl", "3xl", "2xl", "xl", "lg", "md", "sm", "xs"중에서 선택 가능하며,
font_size는 "2em", "40px", "100%", "10vw" 등 CSS 방식으로 표현 가능합니다.

코드 예시

def index():
    return pc.vstack(
        pc.heading("Hello World!", font_size="10vw", color="blue"),  # 뷰포트(브라우저화면) 너비의 10% 사이즈
        pc.heading("Hello World!", size="4xl", color="green"),
        pc.heading("Hello World!", size="2xl", color="red"),
        pc.heading("Hello World!", font_size="200%", color="orange"),
    )

구현화면

 

pc.input

사용자로부터 한 줄의 텍스트를 입력으로 받는 폼 컴포넌트입니다.
이와 유사한 인풋 컴포넌트로는
숫자만 입력으로 받는 pc.numbe_rinput,
암호나 핀번호를 입력받는 pc.pin_input 등이 있으며
여러 줄의 텍스트를 받는 pc.text_area도 있습니다.

코드 예시

class State(pc.State):
    text: str


def index():
    return pc.center(
        pc.vstack(
            pc.text(State.text),
            pc.input(on_change=State.set_text),
        )
    )

구현화면

 

pc.button

일반적인 버튼 컴포넌트입니다.
pc.button_group으로 버튼들을 묶을 수도 있으며,
버튼 안에 is_loading이나 is_disabled 등을 지정하여
특정 상태를 부여할 수도 있습니다.

코드 예시

class State(pc.State):
    count: int = 0

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

    def dec(self):
        self.count -= 1


def index():
    return pc.center(
        pc.button_group(
            pc.button(pc.icon(tag="MinusIcon"), color_scheme="red", on_click=State.dec),
            pc.button(State.count),
            pc.button(pc.icon(tag="AddIcon"), color_scheme="green", on_click=State.inc),
            is_attached=True,
        )
    )

구현화면

 

pc.divider

컴포넌트 사이에 회색의 구분선을 그려줍니다.
orientation="vertical" | "horizontal" 파라미터로 가로세로를 정할 수 있고,
variant="solid" | "dashed" 파라미터로 실선과 점선을 그릴 수 있습니다.

코드 예제

def index():
    return pc.center(
        pc.vstack(
            pc.hstack(
                pc.text("Hello"),
                pc.divider(orientation="vertical", height="2em"),
                pc.text("World"),
            ),
            pc.divider(),
            pc.hstack(
                pc.text("Foo"),
                pc.divider(orientation="vertical", height="2em"),
                pc.text("Bar"),
                pc.divider(orientation="vertical", height="2em"),
                pc.text("Baz")
            ),
        )
    )

구현화면

 

pc.cond

if문과 유사한 pynecone의 조건문입니다.
첫 번째 인자로 조건(bool),
두 번째 인자는 조건이 참일 경우에만 화면에 렌더링할 컴포넌트,
옵션으로 세 번째 인자를 주면 조건이 거짓일 경우에만
화면에 렌더링할 컴포넌트를 지정할 수 있습니다.

코드 예시

class State(pc.State):
    show: bool = True

    def change(self):
        self.show = not (self.show)


def index():
    return pc.vstack(
        pc.button("Toggle", on_click=State.change),
        pc.cond(
            State.show,
            pc.text("Hello", color="blue"),
            pc.text("World", color="red"),
        ),
    )

구현화면

 

pc.circular_progress

프로세스의 진행정도를 나타내거나,
현재 진행중임을 나타내는 원형 프로그레스바입니다.
pc.cond 컴포넌트와 연동하여 쓰이는 경우가 많습니다.
(우리 이미지생성기 앱에서도 pc.cond와 연동하여 사용할 예정입니다.)

가급적 아래 코드의 구조는 꼭 지금 익혀두시면 좋겠습니다.

고작 프로그레스바 하나를 그리기 위해
왜 State 속성과 메서드가 각각 두 개씩이나 필요한지
처음에는 이해하기 힘드실 수 있지만
몇 번만 직접 구현해보시면 금세 이해하시게 될 겁니다.
중요합니다.

 

코드 예시

class State(pc.State):
    progress: bool = False
    complete: bool = False

    def doing(self):
        self.progress = True
        self.complete = False

    def done(self):
        sleep(3)
        self.progress = False
        self.complete = True


def index():
    return pc.vstack(
        pc.button("Start", on_click=[State.doing, State.done]),
        pc.cond(State.progress, pc.circular_progress(is_indeterminate=True)),
        pc.cond(State.complete, pc.text("Mission complete!!"))
    )

구현화면

 

pc.hstack

vstack과 유사하게 컴포넌트를 가로방향으로 쌓아줍니다.
참고로 hstack과 vstack을 조합하면
pc.grid 컴포넌트와 유사하면서도 간단하게
일종의 격자 레이아웃을 만들 수 있습니다.

코드 예시

def index():
    img = pc.image(src="https://i.pinimg.com/564x/46/e6/b1/46e6b1a10e0dfce12a770a0aab29b1ec.jpg", width="30vh")
    return pc.vstack(
        pc.hstack(img, img, img, img),
        pc.hstack(img, img, img, img),
    )

구현화면

pc.image

<img src=""> 태그와 유사합니다.

코드 예시

def index():
    return pc.center(
        pc.image(src="https://blog.kakaocdn.net/dn/dECMql/btrYpnRHYLF/NANk86DANrdoLleGNcTFF0/img.jpg",
                 width="auto",
                 height="95vh",
                 border_radius="15px 50px",
                 border="5px solid skyblue",
                 padding="5px",
                 ),
        width="100%", height="100vh"
    )

구현화면


여기까지
우리가 이번에 사용할 10개의 컴포넌트를
모두 알아보았습니다.

어떠셨나요?
아직은 어렵고 막연하게 느껴지는 컴포넌트가 있겠습니다만,
차근차근 따라해보시면서 코드를 몇 번씩 읽어보시면
코드의 의도도 파악하게 되고, 점점 익숙해지시리라 믿습니다.
다음 포스팅부터는
본격적으로 이미지생성 앱을 만들어보겠습니다.
다소 생소하고 어렵더라도
저를 믿고 차근차근 따라와주시면
어느 순간 파인콘이 쉽다고 생각하는 여러분의 모습을
직접 보시게 될 겁니다. 정말이에요^^

Don't believe me, just watch!

 

그럼 다음 포스팅에서 뵙겠습니다!

2023.02.16 - [pynecone 튜토리얼] - [pynecone] Dall-E 2 이미지 생성 앱 만들기④

 

[pynecone] Dall-E 2 이미지 생성 앱 만들기④

들어가기 전에 지난 시간에는 작정하고 우리 앱에 들어가는 파인콘 컴포넌트 10개를 모두 짚어보았습니다. 사실 컴포넌트가 어떻게 작동하고 어떤 속성을 지녔는지를 파악했다면, 이들을 배치

martinii.fun

 

댓글