Essayez la programmation GUI avec Hy

Cet article est l'article du 16ème jour du Calendrier de l'Avent Lisp 2019.

Résumé de cet article

En guise d'introduction à la programmation GUI dans Hy, l'art génératif utilisant la bibliothèque GUI tkinter inclus dans la bibliothèque Python standard. Implémenter.

C'est une spécification que vous pouvez modifier les paramètres par entrée clé dans le dessin d'une figure en utilisant une fonction triangulaire comme celle-ci. 2019-12-15_23h18_53.png

Public cible

Environnement

L'environnement de l'auteur est le suivant.

Construire un environnement virtuel et installer des modules

La bibliothèque GUI tkinter est une bibliothèque Python standard, Hy est donc le seul module tiers à installer dans un environnement virtuel. Hy a installé la dernière version en date du 12/10 (https://github.com/hylang/hy/tree/39c150d8299d9ff8f47bb78415e22a9fe976d7e5).

cd %USERPROFILE$\.virtualenvs
py -3 -m venv venv_hy_geometric_pattern
cd venv_hy_geometric_pattern
Scripts\activate.bat
pip install --upgrade pip
pip install git+https://github.com/hylang/hy.git
deactivate

spécification

tk.Tk () Créez un canevas dans la fenêtre créée en tant qu'occurrence et dessinez-y une figure. Redessinez le canevas à environ 60 ips pour l'animation. Les coordonnées d'un point à un certain moment sont calculées par la formule suivante. Changez $ \ theta $ par $ \ mathrm {d} \ theta $ pour créer un tableau de points à ce moment-là.

\left\{ \begin{array}{}
x(\theta , t) = x_{\mathrm{center}} + r \cos \theta + a \cos (\phi \left( t \right) + c \theta) \\

y(\theta , t) = y_{\mathrm{center}} + r \sin \theta + a \sin (\phi \left( t \right) + c \theta)
\end{array} \right.
0 \leq \theta < 2 \pi \\
0 \leq \phi < 2 \pi \\
0 \leq c < 2 \pi \\
0 < r + a < \min(x_{\mathrm{center}}, y_{\mathrm{center}}) \\

$ \ left (x_ {\ mathrm {center}}, y_ {\ mathrm {center}} \ right) $ est la coordonnée centrale du canevas. $ \ phi $ fait boucler $ 0 \ leq \ phi <2 \ pi $ dans le temps.

Vous permet de changer la taille de pas $ \ mathrm {d} \ theta $ de $ r, a, c $ et $ \ theta $ ci-dessus par saisie. Les affectations des touches sont indiquées dans le tableau ci-dessous. Il définit également la touche q pour fermer et quitter la fenêtre.

variable Diminuer la clé Augmenter la clé
r z a
a x s
c c d
\mathrm{d} \theta v f

Configuration du package

hySupposons que le répertoire a été ajouté à pythonpath. Le contenu de \ _ \ _ init \ _ \ _. Hy est vide, et nous implémenterons la fonction dans gui.hy. Appelez et exécutez Geometric_pattern.gui à partir de Geometric_pattern.bat.

hy ─┬─ geometric_pattern ─┬─ __init__.hy
    │                     │
    │                     └─ gui.hy
    │
    └─ geometric_pattern.bat

la mise en oeuvre

gui.hy


(import [math [sin cos radians]])
(import sys)
(import [tkinter :as tk])

;Taille de la toile
(setv *width* 800)
(setv *height* 600)


(defclass GeometricPattern []
  (setv *d-theta-max* 20)
  (setv *deg* 360)
  (setv *d-phi* 1)

  (defn --init-- [self &optional [center-x 0] [center-y 0]]
    "Initialisez les paramètres et obtenez une liste de points"
    (setv (. self center-x) center-x)
    (setv (. self center-y) center-y)

    (setv (. self r)
          (int (-> 0.8
                   (* (min (. self center-x) (. self center-y)))
                   (/ 3))))
    (setv (. self a)
          (int (-> 0.8
                   (* 2 (min (. self center-x) (. self center-y)))
                   (/ 3))))
    (setv (. self phi) 0)
    (setv (. self c) 104)

    ;;Largeur de pas lors du changement de thêta
    (setv (. self d-theta) 1)

    ((. self fetch-points)))
  
  (defn dec-r [self event]
    "Diminuer r"
    (setv (. self r) (dec (. self r)))
    (if (< (. self r) 1)
        (setv (. self r) 1)))

  (defn inc-r [self event]
    "Augmentez r. La limite supérieure est spécifiée afin qu'elle ne dépasse pas du côté court de Canvas"
    (if (< (+ (. self r) (. self a))
           (min (. self center-x) (. self center-y)))
        (setv (. self r) (inc (. self r)))))
  
  (defn dec-a [self event]
    "Diminuer un"
    (setv (. self a) (dec (. self a)))
    (if (< (. self a) 1)
        (setv (. self a) 1)))
  
  (defn inc-a [self event]
    "Augmentez a. La limite supérieure est spécifiée afin qu'elle ne dépasse pas du côté court de Canvas"
    (if (< (+ (. self r) (. self a))
           (min (. self center-x) (. self center-y)))
        (setv (. self a) (inc (. self a)))))
  
  (defn dec-d-theta [self event]
    (setv (. self d-theta) (dec (. self d-theta)))
    (if (< (. self d-theta) 1)
        (setv (. self d-theta) 1)))
  
  (defn inc-d-theta [self event]
    (setv (. self d-theta) (inc (. self d-theta)))
    (if (> (. self d-theta) (. GeometricPattern *d-theta-max*))
        (setv (. self d-theta) (. GeometricPattern *d-theta-max*))))
  
  (defn dec-c [self event]
    (setv (. self c) (dec (. self c)))
    (if (< (. self c) 0)
        (setv (. self c) (% (. self c) (. GeometricPattern *deg*)))))
  
  (defn inc-c [self event]
    (setv (. self c) (inc (. self c)))
    (if (>= (. self c) (. GeometricPattern *deg*))
        (setv (. self c) (% (. self c) (. GeometricPattern *deg*)))))

  (defn inc-phi [self]
    (setv (. self phi) (inc (. self phi)))
    (setv (. self phi) (% (. self phi) (. GeometricPattern *deg*))))
  
  (defn fetch-points [self]
    "Obtenir les coordonnées d'un point"
    (setv (. self points)
          (lfor theta (range 0 (. GeometricPattern *deg*) (. self d-theta))
                (, (+ (+ (. self center-x) (* (. self r) (cos (radians theta))))
                      (* (. self a) (cos (radians (+ (. self phi) (* (. self c) theta))))))
                   (+ (+ (. self center-y) (* (. self r) (sin (radians theta))))
                      (* (. self a) (sin (radians (+ (. self phi) (* (. self c) theta)))))))))

    ;;Ajoutez le premier point à la fin de la liste pour fermer le chemin
    ((. self points append) (. self points [0]))))


(defclass Simulator []
  (setv *ms* 16)
  
  (defn --init-- [self width height]
    (setv (. self width) width)
    (setv (. self height) height)

    ;;Initialisation de la fenêtre et du canevas
    (setv (. self window) ((. tk Tk)))
    ((. self window title) :string "Sample Trig Function on Tkinter")
    ((. self window resizable) :width False :height False)
    (setv (. self canvas)
          ((. tk Canvas) (. self window)
                         :width (. self width)
                         :height (. self height)))

    (setv (. self center-x) (/ width 2))
    (setv (. self center-y) (/ height 2))

    ;;Coordonnées des caractères à afficher
    (setv (. self quit-x) 20)
    (setv (. self quit-y) 30)
    (setv (. self r-x) (- width 20))
    (setv (. self r-y) (- height 120))
    (setv (. self a-x) (- width 20))
    (setv (. self a-y) (- height 90))
    (setv (. self c-x) (- width 20))
    (setv (. self c-y) (- height 60))
    (setv (. self d-theta-x) (- width 20))
    (setv (. self d-theta-y) (- height 30))

    (setv (. self gp) (GeometricPattern (. self center-x) (. self center-y)))

    ;;Remplissez la toile avec la couleur d'arrière-plan (noir)
    ((. self canvas create-rectangle) 0
                                      0
                                      (. self width)
                                      (. self height)
                                      :fill "black")
    ((. self draw))
    ((. self canvas pack))

    ;;Paramètres de liaison des clés
    ((. self window bind) "<KeyPress-q>" (. self quit))
    ((. self window bind) "<KeyPress-z>" (. self gp dec-r))
    ((. self window bind) "<KeyPress-a>" (. self gp inc-r))
    ((. self window bind) "<KeyPress-x>" (. self gp dec-a))
    ((. self window bind) "<KeyPress-s>" (. self gp inc-a))
    ((. self window bind) "<KeyPress-c>" (. self gp dec-c))
    ((. self window bind) "<KeyPress-d>" (. self gp inc-c))
    ((. self window bind) "<KeyPress-v>" (. self gp dec-d-theta))
    ((. self window bind) "<KeyPress-f>" (. self gp inc-d-theta)))
  
  (defn quit [self event]
    ((. self window destroy)))
  
  (defn draw [self]

    ;;Dessiner une figure
    ((. self canvas create-line) (. self gp points) :fill "white" :tag "sample")
    
    ;;Dessiner des personnages
    ((. self canvas create-text) (. self quit-x)
                                 (. self quit-y)
                                 :text "Quit: q"
                                 :tag "sample"
                                 :font (, "Arial" 12)
                                 :fill "white"
                                 :anchor (. tk W))
    ((. self canvas create-text) (. self r-x)
                                 (. self r-y)
                                 :text ((. "r: Z < {0:03d} > A" format) (. self gp r))
                                 :tag "sample"
                                 :font (, "Arial" 12)
                                 :fill "white"
                                 :anchor (. tk E))
    ((. self canvas create-text) (. self a-x)
                                 (. self a-y)
                                 :text ((. "a: X < {0:03d} > S" format) (. self gp a))
                                 :tag "sample"
                                 :font (, "Arial" 12)
                                 :fill "white"
                                 :anchor (. tk E))
    ((. self canvas create-text) (. self c-x)
                                 (. self c-y)
                                 :text ((. "c: C < {0:03d} > D" format) (. self gp c))
                                 :tag "sample"
                                 :font (, "Arial" 12)
                                 :fill "white"
                                 :anchor (. tk E))
    ((. self canvas create-text) (. self d-theta-x)
                                 (. self d-theta-y)
                                 :text ((. "d-theta: V < {0:03d} > F" format) (. self gp d-theta))
                                 :tag "sample"
                                 :font (, "Arial" 12)
                                 :fill "white"
                                 :anchor (. tk E)))
  
  (defn delete [self]
    "Supprimer l'élément avec la balise exemple"
    ((. self canvas delete) "sample"))
  
  (defn loop [self]
    ;;Effacer l'écran précédent
    ((. self delete))

    ;;Obtenez un nouvel état et dessinez
    ((. self gp inc-phi))
    ((. self gp fetch-points))
    ((. self draw))

    ;;Exécuter la boucle après environ 16 ms
    ((. self window after) (. Simulator *ms*) (. self loop))))


(defn main []
  (setv simulator (Simulator *width* *height*))
  ((. simulator loop))
  ((. simulator window mainloop))
  0)


(when (= --name-- "__main__")
      ((. sys exit) (main)))

Créez un fichier de commandes pour appeler et exécuter le module géométrique_pattern.gui ci-dessus. Activer l'environnement virtuel pour que la commande `hy``` et le module hy soient dans le chemin. Exécutez ensuite le module Geometric_pattern.gui avec la commande hy ''. Avec l'option -m, vous pouvez spécifier les modules du package en notation séparée par des points.

geometric_pattern.bat


@ECHO OFF
SETLOCAL

SET THISDIR=%~dp0
SET PYTHONPATH=%THISDIR%;%PYTHONPATH%
SET ACTIVATE=%USERPROFILE%\.virtualenvs\venv_hy_geometric_pattern\Scripts\activate.bat

CALL %ACTIVATE%
hy -m geometric_pattern.gui
SET STATUS=%ERRORLEVEL%
CALL deactivate

IF %STATUS%==0 (
  ECHO Done.
  PAUSE
  EXIT /b 0
) ELSE (
  ECHO Error.
  PAUSE
  EXIT /b 1
)

Courir

Faisons le.

2019-12-16_15h26_49.png 2019-12-16_15h26_58.png 2019-12-16_15h27_25.png 2019-12-16_15h27_30.png

Oui. Il peut être amusant de changer la couleur et l'épaisseur du tracé ou de le changer en une autre formule.

Résumé / Supplément

Recommended Posts

Essayez la programmation GUI avec Hy
Essayez de programmer avec un shell!
Programmation GUI à l'aide de kivy ~ Partie 4 Divers boutons ~
Programmation GUI à l'aide de kivy ~ Partie 5 Création de boutons avec des images ~
Essayez de gratter avec Python.
Programmation asynchrone avec libev # 2
3. 3. Programmation IA avec Python
Programmation Python avec Atom
Programmation compétitive avec python
Programmation Shader avec pyOpenGL
Essayez SNN avec BindsNET
Programmation asynchrone avec libev
Programmation linéaire avec PuLP
Essayez la régression avec TensorFlow
Programmation avec Python Flask
Programmation asynchrone avec libev # 3
Essayez de résoudre le livre des défis de programmation avec python3
Programmation GUI avec kivy ~ Partie 3 Vidéo et barre de recherche ~
Programmation avec Python et Tkinter
Essayez de défier le sol par récursif
Essayez l'optimisation des fonctions avec Optuna
Essayez d'utiliser PythonTex avec Texpad.
Essayez la programmation Linux normale, partie 7
Essayez la détection des bords avec OpenCV
Essayez d'implémenter RBM avec chainer.
Essayez Google Mock avec C
Essayez Auto Encoder avec Pytorch
Création d'outils GUI avec pyinstaller
Essayez la sortie Python avec Haxe 3.2
Essayez l'opération matricielle avec NumPy
Essayez la programmation Linux normale, partie 2
Essayez d'implémenter XOR avec PyTorch
Essayez d'exécuter CNN avec ChainerRL
Essayez différentes choses avec PhantomJS
Jeu éducatif de programmation avec SenseHAT
Essayez la programmation Linux normale, partie 3
Essayez le Deep Learning avec FPGA
Apprentissage par renforcement 5 Essayez de programmer CartPole?
[GUI en Python] PyQt5-Layout management-
Essayez la programmation Linux normale, partie 4
Essayez d'exécuter Python avec Try Jupyter
Essayez d'implémenter le parfum avec Go
Essayez la programmation Linux normale, partie 6
Essayez Selenium Grid avec Docker
Essayez la reconnaissance faciale avec Python
Essayez OpenCV avec Google Colaboratory
[GUI avec Python] PyQt5-Préparation-
Essayez le machine learning à la légère avec Kaggle
Essayez TensorFlow MNIST avec RNN
Programmation réseau avec Python Scapy
Essayez de créer Jupyter Hub avec Docker
Essayez d'utiliser le folium avec anaconda
[GUI avec Python] PyQt5 -Paint-
Essayez de gratter avec Python + Beautiful Soup
Programmation GUI en Python avec Appjar
Renforcer l'apprentissage 13 Essayez Mountain_car avec ChainerRL.
[GUI avec Python] PyQt5 -Widget II-
Faisons une interface graphique avec python.
Essayez d'exploiter Facebook avec Python
[Python] Programmation orientée objet apprise avec Pokemon