Mal eine eher funktionale Variante einer Stoppuhr in Hy.
[codebox=clojure file=Unbenannt.txt]#!/usr/bin/env hy
(import
[collections [namedtuple]]
[datetime [datetime :as DateTime timedelta :as TimeDelta]]
[functools [partial]]
[Tkinter :as tk]
[Tkinter [*left* *top*]])
(def *zero-timedelta* (TimeDelta))
(def now (. DateTime utcnow))
(def Stopwatch (namedtuple "Stopwatch" "start_time elapsed_time"))
(defn make-stopwatch []
(reset-stopwatch (Stopwatch None None)))
(defn running-stopwatch? [stopwatch]
(not (none? (. stopwatch start-time))))
(defn get-elapsed-time-stopwatch [stopwatch]
(+ (. stopwatch elapsed-time)
(if (running-stopwatch? stopwatch)
(- (now) (. stopwatch start-time))
*zero-timedelta*)))
(defn reset-stopwatch [stopwatch]
((if (running-stopwatch? stopwatch) start-stopwatch identity)
(Stopwatch (. stopwatch start-time) *zero-timedelta*)))
(defn start-stopwatch [stopwatch]
(Stopwatch (now) (. stopwatch elapsed-time)))
(defn stop-stopwatch [stopwatch]
(Stopwatch None (get-elapsed-time-stopwatch stopwatch)))
(defn toggle-stopwatch [stopwatch]
((if (running-stopwatch? stopwatch) stop-stopwatch start-stopwatch)
stopwatch))
(defn make-stopwatch-ui [parent stopwatch]
(setv ui {}
frame (tk.Frame parent)
timer-id None
elapsed-time-label (tk.Label frame)
button-frame (tk.Frame frame)
toggle-button
(tk.Button frame :command (partial do-something ui toggle-stopwatch))
reset-button
(tk.Button
frame
:text "Reset"
:command (partial do-something ui reset-stopwatch)))
(.pack elapsed-time-label :side *top*)
(.pack toggle-button :side *left*)
(.pack reset-button :side *left*)
(.pack button-frame :side *top*)
(.update ui
{:frame frame
:stopwatch stopwatch
:timer-id timer-id
:elapsed-time-label elapsed-time-label
:toggle-button toggle-button})
(update-ui ui)
ui)
(defn -update-elapsed-time [ui]
(update-elapsed-time ui)
(assoc ui :timer-id (.after (:frame ui) 100 -update-elapsed-time ui)))
(defn update-elapsed-time [ui]
(assoc (:elapsed-time-label ui)
"text" (get-elapsed-time-stopwatch (:stopwatch ui))))
(defn update-ui [ui]
(update-elapsed-time ui)
(setv running? (running-stopwatch? (:stopwatch ui)))
(assoc (:toggle-button ui) "text" (if running? "Stop" "Start"))
(setv timer-id (:timer-id ui))
(if running?
(when (none? timer-id) (-update-elapsed-time ui))
(unless (none? timer-id)
(.after-cancel (:frame ui) timer-id)
(assoc ui :timer-id None))))
(defn do-something [ui func]
(assoc ui :stopwatch (func (:stopwatch ui)))
(update-ui ui))
(defmain [&rest args]
(setv root (tk.Tk))
(.title root "Stoppuhr")
(setv ui (make-stopwatch-ui root (make-stopwatch)))
(.pack (:frame ui))
(.mainloop root))[/code]