반응형

 

Start Bootstrap에서 템플릿을 받아와서 메인 페이지를 구성하겠습니다.

 

1. Start Bootstrap 템플릿 다운로드

우선 Google에서 start bootstrap으로 검색하여 해당 사이트로 이동합니다.

다음으로 Themes 메뉴를 클릭한 다음, Free 옵션을 선택(Pro 해제) 하여 무료 옵션 중에서 적당한 테마를 고릅니다. 클릭하여 나타나는 상세 페이지에서 Download를 해 줍니다. 그리고 Template에서도 블로그용 template를 받아줍니다.

 

 

다운로드 받은 Theme 파일은 아래와 같이 static폴더와 templates폴더에 나누어 넣어줍니다. index.html 파일은 home.html로 이름을 바꾸어줍니다.

 

2. home.html 파일 수정

파일 링크를 참조하는 "src=" 부분과 "href=" 부분을 "src={% static ..... %}", "href={% static ..... %}"와 같이 변경해 줍니다. visual studio code의 바꾸기 기능 중 정규식을 이용하여

from: src="(.*?)" 

to:    src="{% static '$1' %}"

와 같이 하여 하나씩 확인해가면서 바꾸어줍니다. 그리고 만들려고 하는 목적에 맞게 컨텐츠를 수정해줍니다.

{% load static %}

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
        <meta name="description" content="" />
        <meta name="author" content="" />
        <title>Home.html</title>
        <!-- Favicon-->
        <link rel="icon" type="image/x-icon" href="{% static 'assets/favicon.ico' %}" />
        <!-- Font Awesome icons (free version)-->
        <script src="https://use.fontawesome.com/releases/v5.15.4/js/all.js" crossorigin="anonymous"></script>
        <!-- Google fonts-->
        <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css" />
        <link href="https://fonts.googleapis.com/css?family=Roboto+Slab:400,100,300,700" rel="stylesheet" type="text/css" />
        <!-- Core theme CSS (includes Bootstrap)-->
        <link href="{% static 'css/styles.css' %}" rel="stylesheet" />
    </head>
    <body id="page-top">
        <!-- Navigation-->
        <nav class="navbar navbar-expand-lg navbar-dark fixed-top" id="mainNav">
            <div class="container">
                <div class="navbar-brand">Vue - Django Web Programming</div>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
                    Menu
                    <i class="fas fa-bars ms-1"></i>
                </button>
                <div class="collapse navbar-collapse" id="navbarResponsive">
                    <ul class="navbar-nav text-uppercase ms-auto py-4 py-lg-0">
                        <li class="nav-item"><a class="nav-link" href="#page-top">Home</a></li>
                        <li class="nav-item"><a class="nav-link" href="#portfolio">Blog</a></li>
                        <li class="nav-item"><a class="nav-link" href="#team">Iam</a></li>
                        <li class="nav-item"><a class="nav-link" href="{% url 'admin:index' %}">Admin</a></li>
                    </ul>
                </div>
            </div>
        </nav>
        <!-- Masthead-->
        <header class="masthead">
            <div class="container">
                <div class="masthead-subheading">Welcome To My Blog !</div>
                <div style="margin-bottom: 230px;">일상 생활과 관련사항을 기록하고 있습니다.</div>
            </div>
        </header>

        <!-- Blog Grid-->
        <section class="page-section bg-light" id="portfolio">
            <div class="container">
                <div class="text-center">
                    <h2 class="section-heading text-uppercase">Blot List</h2>
                    <h3 class="section-subheading text-muted">Lorem ipsum dolor sit amet consectetur.</h3>
                </div>
                <div class="row">
                    <div class="col-lg-4 col-sm-6 mb-4">
                        <!-- Portfolio item 1-->
                        <div class="portfolio-item">
                            <a class="portfolio-link" data-bs-toggle="modal" href="#portfolioModal1">
                                <div class="portfolio-hover">
                                    <div class="portfolio-hover-content"><i class="fas fa-plus fa-3x"></i></div>
                                </div>
                                <img class="img-fluid" src="{% static 'assets/img/portfolio/1.jpg' %}" alt="..." />
                            </a>
                            <div class="portfolio-caption">
                                <div class="portfolio-caption-heading">Threads</div>
                                <div class="portfolio-caption-subheading text-muted">Illustration</div>
                            </div>
                        </div>
                    </div>
                    <div class="col-lg-4 col-sm-6 mb-4">
                        <!-- Portfolio item 2-->
                        <div class="portfolio-item">
                            <a class="portfolio-link" data-bs-toggle="modal" href="#portfolioModal2">
                                <div class="portfolio-hover">
                                    <div class="portfolio-hover-content"><i class="fas fa-plus fa-3x"></i></div>
                                </div>
                                <img class="img-fluid" src="{% static 'assets/img/portfolio/2.jpg' %}" alt="..." />
                            </a>
                            <div class="portfolio-caption">
                                <div class="portfolio-caption-heading">Explore</div>
                                <div class="portfolio-caption-subheading text-muted">Graphic Design</div>
                            </div>
                        </div>
                    </div>
                    <div class="col-lg-4 col-sm-6 mb-4">
                        <!-- Portfolio item 3-->
                        <div class="portfolio-item">
                            <a class="portfolio-link" data-bs-toggle="modal" href="#portfolioModal3">
                                <div class="portfolio-hover">
                                    <div class="portfolio-hover-content"><i class="fas fa-plus fa-3x"></i></div>
                                </div>
                                <img class="img-fluid" src="{% static 'assets/img/portfolio/3.jpg' %}" alt="..." />
                            </a>
                            <div class="portfolio-caption">
                                <div class="portfolio-caption-heading">Finish</div>
                                <div class="portfolio-caption-subheading text-muted">Identity</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
        <!-- Iam-->
        <section class="page-section bg-light" id="team">
            <div class="container">
                <div class="text-center">
                    <h2 class="section-heading text-uppercase">홍  길  동</h2>
                    <h3 class="section-subheading text-muted">Lorem ipsum dolor sit amet consectetur.</h3>
                </div>
                <div class="row">
                    <div class="col-lg-4">
                        <div class="team-member">
                            <img class="mx-auto rounded-circle" src="{% static 'assets/img/team/1.jpg' %}" alt="..." />
                            <h4>Creative Company</h4>
                            <p class="text-muted">Python Web Programmer</p>
                            <a class="btn btn-dark btn-social mx-2" href="#!"><i class="fab fa-twitter"></i></a>
                            <a class="btn btn-dark btn-social mx-2" href="#!"><i class="fab fa-facebook-f"></i></a>
                            <a class="btn btn-dark btn-social mx-2" href="#!"><i class="fab fa-linkedin-in"></i></a>
                        </div>
                    </div>
                    <div class="col-lg-8">
                        내 소개 내용...
                    </div>
                </div>
            </div>
        </section>
        <!-- Footer-->
        <footer class="footer py-4">
            <div class="container">
                <div class="row align-items-center">
                    <div class="col-lg-4 text-lg-start">Copyright &copy; Your Website 2021</div>
                    <div class="col-lg-4 my-3 my-lg-0">
                        <a class="btn btn-dark btn-social mx-2" href="#!"><i class="fab fa-twitter"></i></a>
                        <a class="btn btn-dark btn-social mx-2" href="#!"><i class="fab fa-facebook-f"></i></a>
                        <a class="btn btn-dark btn-social mx-2" href="#!"><i class="fab fa-linkedin-in"></i></a>
                    </div>
                    <div class="col-lg-4 text-lg-end">
                        <a class="link-dark text-decoration-none me-3" href="#!">Privacy Policy</a>
                        <a class="link-dark text-decoration-none" href="#!">Terms of Use</a>
                    </div>
                </div>
            </div>
        </footer>
        <!-- Bootstrap core JS-->
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"></script>
        <!-- Core theme JS-->
        <script src="{% static 'js/scripts.js' %}"></script>
        <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->
        <!-- * *                               SB Forms JS                               * *-->
        <!-- * * Activate your form at https://startbootstrap.com/solution/contact-forms * *-->
        <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->
        <script src="https://cdn.startbootstrap.com/sb-forms-latest.js"></script>
    </body>
</html>

 

반응형
반응형

1. 프로젝트 생성 ( 가상환경 생성)

 

2. 라이브러리 설치

pip install django

 

3. Django 프로젝트 설치

현재 폴더에 ( . ) mysite라는 프로젝트를 생성해줍니다. 이 경우 manage.py파일이 현재 폴더에 생성됩니다. (현재 폴더를 지정하지 않으면 한단계 더 아래 폴더에 프로젝트 및 manage.py 파일을 생성합니다. )

django-admin startproject mysite .

 

4. setting.py 수정

DB / Template / Media / Static 관련된 폴더들을 만들고, 이들 경로를 BASE_DIR을 기준으로 지정해줍니다. 그리고 TIME_ZONE, USE_TZ 값을 수정해줍니다.

"""
Django settings for mysite project.

Generated by 'django-admin startproject' using Django 3.2.8.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-1tq5c@vtc5f@-^2%sxpu5(42=3^n24fow@i1m*%+h(5#ghx9ml'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'mysite.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],  # 수정
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'mysite.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db' / 'db.sqlite3',  # 수정
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Seoul'  # 수정

USE_I18N = True

USE_L10N = True

USE_TZ = False  # 수정


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

###  추가  ###
STATICFILES_DIRS = (BASE_DIR / 'static',)
# STATIC_ROOT =  # 배포시 사용

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

# AUTH_USER_MODEL =

# LOGGING =

 

5. DB생성

python manage.py migrate

 

6. 관리자계정 생성

python manage.py createsuperuser

 

7. mysite/urls.py 수정

"""adv URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path

from adv.views import HomeView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', HomeView.as_view(), name='home')
]

8. mysite/views.py 생성

from django.views.generic import TemplateView


class HomeView(TemplateView):
    template_name = 'home.html'

9. templates/home.html 생성

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Home.html</title>
</head>
<body>
hello
</body>
</html>

10. 결과 확인

반응형
반응형

키보드 입력에 맞추어 비프음을 내도록 하겠습니다. 이번 프로그램을 위해서는 비프음을 내도록 하는 windsound 모듈과 키보드 인풋을 받아들이는 pynput 모듈이 필요합니다. 그 중 windwound 모듈은 기본으로 내장되어있으니 pynput 모듈만 설치해주도록 합니다.

 

1. 라이브러리 설치

pip install pynput

 

2. pynput모듈

pynput 모듈에서는 on_press 이벤트와 on_release 이벤트에 대해 리스너를 통해 입력받는 방법이 있습니다.

from pynput import keyboard

def on_press(key):
    print('Pressed Key: %s' % key)

def on_release(key):
    print('Pressed Key: %s' % key)
    if key == keyboard.Key.esc: #esc 키가 입력되면 종료
        return False
        
 # 리스너 등록방법1
listener = keyboard.Listener(
     on_press=on_press,
     on_release=on_release)
listener.start()
listener.join()

# 리스너 등록방법2
with keyboard.Listener(
    on_press=on_press,
    on_release=on_release) as listener:
    listener.join()

이런식으로 이용하면 되지만, 이번에는 동기화 방식에 의한 방법으로

from pynput import keyboard
 
with keyboard.Events() as events:
    for event in events:
        if event.key == keyboard.Key.esc:
            print("Exit!!")
            break
        if event.key == keyboard.KeyCode(char='a'):
            print("Pressed:", keyboard.KeyCode(char='a'))

와 같이 사용하려고 합니다. 이벤트의 종류와 상관없이 처리를 하게 됩니다.

 

3. winsound 모듈

winsound.Beep(음계주파수, 지속시간)

와 같이 사용합니다. 연주를 위해서는 음계에 대한 정확한 주파수를 입력해야합니다. 다행스러운 것은 한 옥타브 위의 음에 대해서는 2배의 Frequency에 해당하는 주파수를 갖고 있습니다.

 

4. 전체 소스코드

from pynput import keyboard
import winsound

# 1옥타브: C, C#, D, D#, E, F, F#, G, G#, A, A#, B
pitch = {'c_': 523, 'cs': 554, 'd_': 587, 'ds': 622, 'e_': 659,
         'f_': 698, 'fs': 740, 'g_': 784, 'gs': 831, 'a_': 880,
         'as': 932, 'b_': 988}
# 2옥타브
pitch2={}
for key, value in pitch.items():
    pitch2[key] = value * 2  # 한옥타브 위는 주파수가 2배.
print(pitch2)

# 지속시간
lasting = 100

# The event listener will be running in this block
with keyboard.Events() as events:
    for event in events:
        if event.key == keyboard.Key.esc:
            print("Exit!!")
            break
        elif event.key == keyboard.KeyCode(char='q'):
            winsound.Beep(494, lasting)
        elif event.key == keyboard.KeyCode(char='a'):
            winsound.Beep(pitch['c_'], lasting)
        elif event.key == keyboard.KeyCode(char='w'):
            winsound.Beep(pitch['cs'], lasting)
        elif event.key == keyboard.KeyCode(char='s'):
            winsound.Beep(pitch['d_'], lasting)
        elif event.key == keyboard.KeyCode(char='e'):
            winsound.Beep(pitch['ds'], lasting)
        elif (event.key == keyboard.KeyCode(char='d')) | (event.key == keyboard.KeyCode(char='r')):
            winsound.Beep(pitch['e_'], lasting)
        elif event.key == keyboard.KeyCode(char='f'):
            winsound.Beep(pitch['f_'], lasting)
        elif event.key == keyboard.KeyCode(char='t'):
            winsound.Beep(pitch['fs'], lasting)
        elif event.key == keyboard.KeyCode(char='g'):
            winsound.Beep(pitch['g_'], lasting)
        elif event.key == keyboard.KeyCode(char='y'):
            winsound.Beep(pitch['gs'], lasting)
        elif event.key == keyboard.KeyCode(char='h'):
            winsound.Beep(pitch['a_'], lasting)
        elif event.key == keyboard.KeyCode(char='u'):
            winsound.Beep(pitch['as'], lasting)
        elif (event.key == keyboard.KeyCode(char='j')) | (event.key == keyboard.KeyCode(char='i')):
            winsound.Beep(pitch['b_'], lasting)
        elif event.key == keyboard.KeyCode(char='k'):
            winsound.Beep(pitch2['c_'], lasting)
        elif event.key == keyboard.KeyCode(char='o'):
            winsound.Beep(pitch2['cs'], lasting)
        elif event.key == keyboard.KeyCode(char='l'):
            winsound.Beep(pitch2['d_'], lasting)
        elif event.key == keyboard.KeyCode(char='p'):
            winsound.Beep(pitch2['ds'], lasting)
        elif (event.key == keyboard.KeyCode(char=';')) | (event.key == keyboard.KeyCode(char='[')):
            winsound.Beep(pitch2['e_'], lasting)
        elif event.key == keyboard.KeyCode(char="'"):
            winsound.Beep(pitch2['f_'], lasting)
        elif event.key == keyboard.KeyCode(char="]"):
            winsound.Beep(pitch2['fs'], lasting)

# 빈 키(z,x,c,v... ) 에 대해 추가로 음계 할당
        elif event.key == keyboard.KeyCode(char="z"):
            winsound.Beep(pitch['c_'], lasting)
        elif event.key == keyboard.KeyCode(char="x"):
            winsound.Beep(pitch['d_'], lasting)
        elif event.key == keyboard.KeyCode(char="c"):
            winsound.Beep(pitch['e_'], lasting)
        elif event.key == keyboard.KeyCode(char="v"):
            winsound.Beep(pitch['f_'], lasting)
        elif event.key == keyboard.KeyCode(char="b"):
            winsound.Beep(pitch['g_'], lasting)
        elif event.key == keyboard.KeyCode(char="n"):
            winsound.Beep(pitch['a_'], lasting)
        elif event.key == keyboard.KeyCode(char="m"):
            winsound.Beep(pitch['b_'], lasting)
        elif event.key == keyboard.KeyCode(char=","):
            winsound.Beep(pitch2['c_'], lasting)
        elif event.key == keyboard.KeyCode(char="."):
            winsound.Beep(pitch2['d_'], lasting)
        elif event.key == keyboard.KeyCode(char="/"):
            winsound.Beep(pitch2['e_'], lasting)

 

이상으로 연주 가능한 키보드를 만들어보았습니다.

 

~~끝~~

반응형
반응형

이전 포스팅의 투명한 배경에 이어, 둥근 버튼 구현하기를 알아보겠습니다.

요즘 tkinter와 kivy를 번갈아가며 사용해보고 있는데, 서로 장단점이 존재하네요. 어느것도 완벽한게 없는듯 합니다.

tkinter는 둥근버튼이 없어서 별도로 구현해야 하는 반면 투명한 배경처리가 가능하고,

kivy는 투명한 배경은 안되도 둥근버튼은 쉽게 구현이 되네요. 

import tkinter as tk

root = tk.Tk()
# root.attributes('-alpha', 0.3)  # 앱 전체가 투명해짐
root.wm_attributes("-transparentcolor", "white")

canvas = tk.Canvas(root, width=600, height=300, bg='white')
canvas.grid(columnspan=3, rowspan=3)
hello = tk.Label(root, text="Hello World", font="Raleway", bg='white')
hello.grid(columnspan=3, column=0, row=0)

# 이미지의 사이즈 변경. x방향 1/2, y방향 1/2
btn_img = tk.PhotoImage(file="button.png").subsample(2, 2)
# compound='center'로 이미지의 위치 설정하고 반대편에 텍스트 배치
# (left,right,top,bottom등 가능)
button = tk.Button(root, text="click", image=btn_img, compound='center', borderwidth=0, bg='white')
button.grid(column=1, row=1)

root.mainloop()

 

반응형
반응형

한참 좋다고 다른 GUI라이브러리 공부할 땐 언제고, 투명 기능이 어려워서 다시 tkinter를 손대게 되네요.

아래는 Tkinter로 구현하는 투명 배경 예제입니다. 

import tkinter as tk

root = tk.Tk()
# root.attributes('-alpha', 0.3)  # 앱 전체가 투명해짐
root.wm_attributes("-transparentcolor", "white")	# 흰색을 투명하도록 지정

canvas = tk.Canvas(root, width=600, height=300, bg='white')	# 배경을 흰색으로 지정
canvas.grid(columnspan=3, rowspan=3)
instructions = tk.Label(root, text="Hello World", font="Raleway")
instructions.grid(columnspan=3, column=0, row=0)

root.mainloop()

 

반응형
반응형

파일관리 프로그램 예제입니다.

 

<main.py>

## File Chooser

from kivy.app import App
from kivy.uix.gridlayout import GridLayout

class TopGridLayout(GridLayout):
    def selected(self, directory, filename):
        try:
            self.ids.image.source = filename[0]
        except:
            pass

class TreeApp(App):
    def build(self):
        return TopGridLayout()

if __name__ == '__main__':
    TreeApp().run()

 

<tree.kv>

<TopGridLayout>:
    cols:2
    id:my_widget

    #FileChooserIconView:
    FileChooserListView:
        id:filechooser
        path:'D:\\'
        dirselect: True
        on_selection:my_widget.selected(filechooser.path, filechooser.selection)

    Image:
        id:image
        source:""

 

<결과>

 

한글 지원이 아직 부족하네요.

반응형
반응형

행성들이 가운데 태양을 중심으로 공전하는 모습을 구현해보겠습니다.

 

<main.py>

import math

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.clock import Clock
import math

Window.size = (900, 900)
center_w = Window.size[0]/2
center_h = Window.size[1]/2

class Sun(Widget):
    pass

class Mercury(Widget):
    pass

class Vinus(Widget):
    pass

class Earth(Widget):
    pass

class Mars(Widget):
    pass

class Solar(Widget):
    sw_seconds = 0
    def update(self, nap):  # nap: 증분, dt delta time
        self.sw_seconds += nap

        ## Earth
        E_dis = 300   # 태양으로부터의 거리
        E_r = self.ids.earth.size[0]      # 지구 직경
        E_rv = 45 # 각도도
        self.ids.earth.pos = self.calc_pos(E_dis, E_r, E_rv)

        ## Mercury
        M_dis = 80  # 태양으로부터의 거리
        M_r = self.ids.mercury.size[0]    # 수성 직경
        M_rv = 60  # 시간에 따른 각도
        self.ids.mercury.pos = self.calc_pos(M_dis, M_r, M_rv)

        ## Vinus
        V_dis = 120  # 태양으로부터의 거리
        V_r = self.ids.vinus.size[0]  # 금성 직경
        V_rv = 50  # 시간에 따른 각도
        self.ids.vinus.pos = self.calc_pos(V_dis, V_r, V_rv)

        ## Mars
        MS_dis = 350  # 태양으로부터의 거리
        MS_r = self.ids.mars.size[0]  # 화성 직경
        MS_rv = 30  # 시간에 따른 각도
        self.ids.mars.pos = self.calc_pos(MS_dis, MS_r, MS_rv)



    def calc_pos(self, dis, radius, radial_v):
        degree = radial_v * self.sw_seconds
        pos_x = dis * math.cos(math.pi * degree / 180) + center_w
        pos_y = dis * math.sin(math.pi * degree / 180) + center_h
        pos = (pos_x, pos_y)
        return pos

class SolarApp(App):
    def build(self):
        SolarSystem = Solar()
        Clock.schedule_interval(SolarSystem.update, 1.0 / 60.0)
        return SolarSystem

if __name__ == '__main__':
    SolarApp().run()

 

<solar.kv>

<Sun>:
    size: 50, 50
    canvas:
        Color:
            rgb: 1,0,0
        Ellipse:
            size: self.size
            pos: self.pos

<Mercury>:
    size: 15, 15
    canvas:
        Color:
            rgb: 0,0,1
        Ellipse:
            size: self.size
            pos: self.pos
<Vinus>:
    size: 20, 20
    canvas:
        Color:
            rgb: 1,1,0
        Ellipse:
            size: self.size
            pos: self.pos

<Earth>:
    size: 20, 20
    canvas:
        Color:
            rgb: 0,1,1
        Ellipse:
            size: self.size
            pos: self.pos
<Mars>:
    size: 18, 18
    canvas:
        Color:
            rgb: 1,0.3,0
        Ellipse:
            size: self.size
            pos: self.pos

<Solar>:
    Sun:
        id:sun
        pos: self.parent.center
    Mercury:
        id:mercury
        pos: self.parent.center
    Vinus:
        id:vinus
        pos: self.parent.center
    Earth:
        id:earth
        pos: self.parent.center
    Mars:
        id:mars
        pos: self.parent.center

<결과>

반응형
반응형

1. main.py

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty

class MyGridLayout(Widget):
    name = ObjectProperty(None) # 변수에 아무것도 할당하지 않도록 함
    pizza = ObjectProperty(None)
    color = ObjectProperty(None)

    def press(self):
        name = self.name.text
        pizza = self.pizza.text
        color = self.color.text

        #self.add_widget(Label(text=f'Hello {name} pizza {pizza} color {color}'))
        print(f'Hello {name} pizza {pizza} color {color}')
        self.name.text = ""
        self.pizza.text = ""
        self.color.text = ""

class MyApp(App):
    def build(self):
        return MyGridLayout()

if __name__ == '__main__':
    MyApp().run()

 

2. my.kv

<MyGridLayout>

    name:name
    pizza:pizza
    color: color

    GridLayout:
        cols:1
        size: root.width, root.height
        GridLayout:
            cols:2

            Label:
                text: "Name"
            TextInput:
                id:name
                multiline:False
            Label:
                text: "Favorite Pizza"
            TextInput:
                id:pizza
                multiline:False
            Label:
                text: "Favorite Color"
            TextInput:
                id:color
                multiline:False

        Button:
            text: "Submit"
            font_size: 32
            on_press: root.press()

 

<결과>

반응형

+ Recent posts