[PYTHON] Versuchen Sie die GUI-Programmierung mit Hy

Dieser Artikel ist der Artikel zum 16. Tag von Lisp Adventskalender 2019.

Zusammenfassung dieses Artikels

Als Einführung in die GUI-Programmierung in Hy wird generative Kunst unter Verwendung der GUI-Bibliothek tkinter in die Standard-Python-Bibliothek aufgenommen. Implementieren.

Es ist eine Spezifikation, dass Sie die Parameter durch Tasteneingabe beim Zeichnen einer Figur mit einer Dreiecksfunktion wie dieser ändern können. 2019-12-15_23h18_53.png

Zielgruppe

Umgebung

Die Umgebung des Autors ist wie folgt.

Erstellen einer virtuellen Umgebung und Installieren von Modulen

Die GUI-Bibliothek tkinter ist eine Standard-Python-Bibliothek, daher ist Hy das einzige Modul eines Drittanbieters, das in einer virtuellen Umgebung installiert wird. Hy hat die neueste Version ab 12/10 installiert (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

Spezifikation

Erstellen Sie eine Leinwand in dem Fenster, das als tk.Tk () -Instanz erstellt wurde, und zeichnen Sie eine Figur darin. Zeichnen Sie die Leinwand für Animationen mit ca. 60 fps neu. Die Koordinaten eines Punktes zu einem bestimmten Zeitpunkt werden nach der folgenden Formel berechnet. Ändern Sie $ \ theta $ um $ \ mathrm {d} \ theta $, um zu diesem Zeitpunkt ein Array von Punkten zu erstellen.

\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) $ ist die Mittelkoordinate des Canvas. $ \ phi $ bewirkt, dass $ 0 \ leq \ phi <2 \ pi $ im Laufe der Zeit eine Schleife durchläuft.

Ermöglicht es Ihnen, die Schrittgröße $ \ mathrm {d} \ theta $ von $ r, a, c $ und $ \ theta $ oben durch Eingabe zu ändern. Die Tastenbelegungen sind in der folgenden Tabelle aufgeführt. Außerdem wird die Taste q zum Schließen und Verlassen des Fensters festgelegt.

Variable Schlüssel verringern Schlüssel erhöhen
r z a
a x s
c c d
\mathrm{d} \theta v f

Paketkonfiguration

hyAngenommen, das Verzeichnis wurde zu Pythonpath hinzugefügt. Der Inhalt von \ _ \ _ init \ _ \ _. Hy ist leer, und wir werden die Funktion in gui.hy implementieren. Rufen Sie geometric_pattern.gui aus geometric_pattern.bat auf und führen Sie es aus.

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

Implementierung

gui.hy


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

;Leinwandgröße
(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]]
    "Initialisieren Sie die Parameter und erhalten Sie eine Liste mit Punkten"
    (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)

    ;;Schrittweite beim Thetawechsel
    (setv (. self d-theta) 1)

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

  (defn inc-r [self event]
    "Erhöhen Sie r. Die Obergrenze ist so festgelegt, dass sie nicht aus der kurzen Seite von Canvas herausragt"
    (if (< (+ (. self r) (. self a))
           (min (. self center-x) (. self center-y)))
        (setv (. self r) (inc (. self r)))))
  
  (defn dec-a [self event]
    "Verringern Sie a"
    (setv (. self a) (dec (. self a)))
    (if (< (. self a) 1)
        (setv (. self a) 1)))
  
  (defn inc-a [self event]
    "Erhöhen Sie a. Die Obergrenze ist so festgelegt, dass sie nicht aus der kurzen Seite von Canvas herausragt"
    (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]
    "Holen Sie sich die Koordinaten eines Punktes"
    (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)))))))))

    ;;Fügen Sie den ersten Punkt am Ende der Liste hinzu, um den Pfad zu schließen
    ((. self points append) (. self points [0]))))


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

    ;;Fenster- und Canvas-Initialisierung
    (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))

    ;;Koordinaten der anzuzeigenden Zeichen
    (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)))

    ;;Fülle die Leinwand mit der Hintergrundfarbe (schwarz)
    ((. self canvas create-rectangle) 0
                                      0
                                      (. self width)
                                      (. self height)
                                      :fill "black")
    ((. self draw))
    ((. self canvas pack))

    ;;Einstellungen für die Schlüsselbindung
    ((. 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]

    ;;Eine Figur zeichnen
    ((. self canvas create-line) (. self gp points) :fill "white" :tag "sample")
    
    ;;Zeichen zeichnen
    ((. 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]
    "Löschen Sie das Element mit dem Beispiel-Tag"
    ((. self canvas delete) "sample"))
  
  (defn loop [self]
    ;;Löschen Sie den vorherigen Bildschirm
    ((. self delete))

    ;;Holen Sie sich neuen Zustand und zeichnen
    ((. self gp inc-phi))
    ((. self gp fetch-points))
    ((. self draw))

    ;;Schleife nach ca. 16ms ausführen
    ((. 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)))

Erstellen Sie eine Batch-Datei, um das obige geometric_pattern.gui-Modul aufzurufen und auszuführen. `Aktiviere``` die virtuelle Umgebung, so dass sich der Befehl` hy und das hy-Modul im Pfad befinden. Führen Sie dann das Modul geometric_pattern.gui mit dem Befehl `` `hy aus. Mit der Option -m können Sie die Module im Paket in punktgetrennter Notation angeben.

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
)

Lauf

Machen wir das.

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

Ja. Es kann Spaß machen, die Farbe und Dicke des Pfades oder eine andere Formel zu ändern.

Zusammenfassung / Ergänzung

Recommended Posts

Versuchen Sie die GUI-Programmierung mit Hy
Versuchen Sie, mit einer Shell zu programmieren!
GUI-Programmierung mit kivy ~ Teil 4 Verschiedene Tasten ~
GUI-Programmierung mit kivy ~ Teil 5 Erstellen von Schaltflächen mit Bildern ~
Versuchen Sie es mit Python.
Asynchrone Programmierung mit libev # 2
3. 3. KI-Programmierung mit Python
Python-Programmierung mit Atom
Wettbewerbsfähige Programmierung mit Python
Shader-Programmierung mit pyOpenGL
Versuchen Sie SNN mit BindsNET
Asynchrone Programmierung mit libev
Lineare Programmierung mit PuLP
Versuchen Sie eine Regression mit TensorFlow
Programmieren mit Python Flask
Asynchrone Programmierung mit libev # 3
Versuchen Sie, das Programmier-Herausforderungsbuch mit Python3 zu lösen
GUI-Programmierung mit kivy ~ Teil 3 Video und Suchleiste ~
Programmieren mit Python und Tkinter
Versuchen Sie, den Boden durch Rekursion herauszufordern
Versuchen Sie die Funktionsoptimierung mit Optuna
Versuchen Sie, PythonTex mit Texpad zu verwenden.
Versuchen Sie es mit normaler Linux-Programmierung Teil 7
Versuchen Sie die Kantenerkennung mit OpenCV
Versuchen Sie, RBM mit Chainer zu implementieren.
Versuchen Sie Google Mock mit C.
Versuchen Sie Auto Encoder mit Pytorch
Erstellen von GUI-Tools mit Pyinstaller
Probieren Sie die Python-Ausgabe mit Haxe 3.2 aus
Versuchen Sie die Matrixoperation mit NumPy
Versuchen Sie es mit normaler Linux-Programmierung Teil 2
Versuchen Sie, XOR mit PyTorch zu implementieren
Versuchen Sie, CNN mit ChainerRL auszuführen
Probieren Sie verschiedene Dinge mit PhantomJS aus
Programmier-Lernspiel mit SenseHAT
Versuchen Sie es mit normaler Linux-Programmierung Teil 3
Versuchen Sie Deep Learning mit FPGA
Verstärkungslernen 5 Versuchen Sie, CartPole zu programmieren?
[GUI in Python] PyQt5-Layout-Management-
Versuchen Sie es mit normaler Linux-Programmierung Teil 4
Versuchen Sie, Python mit Try Jupyter auszuführen
Versuchen Sie, Parfüm mit Go zu implementieren
Versuchen Sie es mit normaler Linux-Programmierung Teil 6
Probieren Sie Selenium Grid mit Docker aus
Versuchen Sie die Gesichtserkennung mit Python
Probieren Sie OpenCV mit Google Colaboratory aus
[GUI mit Python] PyQt5-Vorbereitung-
Versuchen Sie es mit Kaggle leicht maschinell
Versuchen Sie TensorFlow MNIST mit RNN
Netzwerkprogrammierung mit Python Scapy
Versuchen Sie, Jupyter Hub mit Docker zu erstellen
Versuchen Sie es mit Folium mit Anakonda
[GUI mit Python] PyQt5 -Paint-
Versuchen Sie es mit Python + Beautiful Soup
GUI-Programmierung in Python mit Appjar
Lernen stärken 13 Probieren Sie Mountain_car mit ChainerRL aus.
[GUI mit Python] PyQt5 -Widget II-
Lassen Sie uns eine GUI mit Python erstellen.
Versuchen Sie, Facebook mit Python zu betreiben
[Python] Mit Pokemon erlernte objektorientierte Programmierung