Seite 1 von 1

Uhrzeiger Analoguhr

Verfasst: Donnerstag 23. März 2017, 13:29
von XCDRiVER
Hallo Forum,
gibt es schon eine fertige Funktion oder Bibliothek für eine Art Uhrzeiger?
Ich brauchte so etwas für eine Positionsanzeige an einem Kreis-Canvas, ähnlich dem Strich an einem Drehregler oder Poti.
Vielen Dank

P.S. kann den Thread leider nicht mehr entfernen, hab gerade eine schöne Lösung gefunden, danke soweit.

Re: Uhrzeiger Analoguhr

Verfasst: Donnerstag 23. März 2017, 18:14
von XCDRiVER
Ich hab hier meine Lösung für den rotierenden Zeiger mal angehangen,
das Programm funktioniert so erst mal ganz gut.
gibt es vielleicht Funktionen mit denen ich den Code noch kürzen kann?

Außerdem bräuchte ich in dem Zusammenhang noch eine Funktion, die beim Arduino map() heißt.
damit können Wertebereiche in ein verändertes Verhältnis gesetzt werden. So eine Art erweiterter Dreisatz.
Gibt es so etwas schon in einer Bibliothek?

Code: Alles auswählen

from tkinter import Tk, Frame, Canvas
from math import sin, cos, radians

class mainWindow(Frame):
    def __init__(self, master=None):
        super(mainWindow, self).__init__(master)
        self.pack()
        self.cv = Canvas(self, width=200, height=200)
        self.cv.pack()
        self.uhr()
        self.zeigerBewegung()

    def uhr(self):
        self.x0 = 25
        self.y0 = 25
        self.x1 = 175
        self.y1 = 175
        self.schrittweite = 1
        self.zeigerPosition = 0 # Bereich 0 bis 360 Grad

        self.zeigerLaenge = (self.x1 - self.x0)/2
        self.center_x = ((self.x1 - self.x0)/2) + self.x0
        self.center_y = ((self.y1 - self.y0)/2) + self.y0

        self.cv.create_oval(self.x0, self.y0, self.x1, self.y1)
        self.zeiger = self.cv.create_line(self.center_x, self.center_y, self.center_x, self.center_y) # beim start nur als Punkt

    def zeigerBewegung(self):
        x = self.zeigerLaenge * sin(radians(self.zeigerPosition)) + self.center_x
        y = self.zeigerLaenge * cos(radians(180 + self.zeigerPosition)) + self.center_y

        self.cv.coords(self.zeiger, self.center_x, self.center_y, x, y)
        self.zeigerPosition += self.schrittweite
        if self.zeigerPosition > 360:
            self.zeigerPosition = self.zeigerPosition - 360
        self.after(50, self.zeigerBewegung)

if __name__ == "__main__":

    root = Tk()
    fenster = mainWindow(master=root)
    fenster.mainloop()

Re: Uhrzeiger Analoguhr

Verfasst: Donnerstag 23. März 2017, 18:35
von BlackJack
Eine solche `map()`-Funktion gibt's nicht. Aber in der Arduino-Dokumentation steht ja die Implementierung der Funktion. In Python solltest Du sie nur nicht `map()` nennen, denn eine `map()`-Funktion die etwas ganz anderes macht, gibt es in Python ja bereits bei den eingebauten Funktionen. :-)

Re: Uhrzeiger Analoguhr

Verfasst: Donnerstag 23. März 2017, 18:43
von XCDRiVER
ah ok, ich danke dir für info

Re: Uhrzeiger Analoguhr

Verfasst: Donnerstag 23. März 2017, 19:02
von Sirius3
@XCDRiVER: Frames sollten sich nicht selbst positionieren, das pack gehört also aus __init__ heraus in main. In __init__ sollten schon alle Attribute angelegt werden. Die Attribute x0, y0, x1 und y1 werden sowieso nicht gebraucht. Die Zahlen würde ich über __init__ konfigurierbar machen und die Methode uhr weglassen.

Re: Uhrzeiger Analoguhr

Verfasst: Donnerstag 23. März 2017, 19:22
von XCDRiVER
danke für die Info, ich korrigiere das und lade es noch mal rauf

Re: Uhrzeiger Analoguhr

Verfasst: Donnerstag 23. März 2017, 22:21
von XCDRiVER
@Sirius3: ich denke so hattest du das gemeint?

Code: Alles auswählen

from tkinter import Tk, Frame, Canvas
from math import sin, cos, radians

class mainWindow(Frame):
    def __init__(self, koordinate_1, koordinate_2, master=None):
        super(mainWindow, self).__init__(master)
        # self.pack()
        self.x0 = koordinate_1
        self.y0 = koordinate_1
        self.x1 = koordinate_2
        self.y1 = koordinate_2
        self.zeigerPosition = 0 # Bereich 0 bis 360 Grad
        self.zeigerLaenge = (self.x1 - self.x0)/2
        self.center_x = ((self.x1 - self.x0)/2) + self.x0
        self.center_y = ((self.y1 - self.y0)/2) + self.y0
        self.cv = Canvas(self, width=200, height=200)
        self.cv.create_oval(self.x0, self.y0, self.x1, self.y1)
        # self.cv.pack()
        self.zeiger = self.cv.create_line(self.center_x, self.center_y, self.center_x, self.center_y) # beim start nur als Punkt
        self.zeigerBewegung()

    def zeigerBewegung(self):
        x = self.zeigerLaenge * sin(radians(self.zeigerPosition)) + self.center_x
        y = self.zeigerLaenge * cos(radians(180 + self.zeigerPosition)) + self.center_y

        self.cv.coords(self.zeiger, self.center_x, self.center_y, x, y)
        self.zeigerPosition += 1
        if self.zeigerPosition > 360:
            self.zeigerPosition = self.zeigerPosition - 360
        self.after(2, self.zeigerBewegung)

if __name__ == "__main__":

    root = Tk()
    fenster = mainWindow(10, 190, master=root)
    fenster.pack()
    fenster.cv.pack()
    fenster.mainloop()

Re: Uhrzeiger Analoguhr

Verfasst: Donnerstag 23. März 2017, 22:37
von BlackJack
Das ``fenster.cv.pack()`` gehört da nicht hin. Du solltest den abgeleiteten Frame selbst sich selbst nicht anordnen lassen, weil das nicht seine Aufgabe ist. Der ist aber sehr wohl für seinen Inhalt zuständig.

Ich würde auch das Attribut nicht abkürzen. `cv` ist eine übliche Abkürzung für einen Lebenslauf („Curriculum Vitae“).

Re: Uhrzeiger Analoguhr

Verfasst: Donnerstag 23. März 2017, 23:25
von XCDRiVER
@BlackJack: danke, ich ändere das
den StyleGuide muss ich mir sicher mal anschauen

Re: Uhrzeiger Analoguhr

Verfasst: Sonntag 26. März 2017, 19:01
von XCDRiVER
die Wertebegrenzung (Winkel) habe ich wieder raus genommen, die war in diesem Zusammenhang unnötig.
ich würde es für dieses Testfile dabei belassen,
vielen Dank euch beiden.

Code: Alles auswählen

from tkinter import Tk, Frame, Canvas
from math import sin, cos, radians

class mainWindow(Frame):
    def __init__(self, koordinate_1, koordinate_2, master=None):
        super(mainWindow, self).__init__(master)
        self.x0 = koordinate_1
        self.y0 = koordinate_1
        self.x1 = koordinate_2
        self.y1 = koordinate_2
        self.zeigerPosition = 0
        self.zeigerLaenge = (self.x1 - self.x0)/2
        self.center_x = ((self.x1 - self.x0)/2) + self.x0
        self.center_y = ((self.y1 - self.y0)/2) + self.y0
        self.leinwand = Canvas(self, width=200, height=200)
        self.leinwand.pack()
        self.leinwand.create_oval(self.x0, self.y0, self.x1, self.y1)
        self.zeiger = self.leinwand.create_line(self.center_x, self.center_y, self.center_x, self.center_y) # beim start nur als Punkt
        self.zeigerBewegung()

    def zeigerBewegung(self):
        x = self.zeigerLaenge * sin(radians(self.zeigerPosition)) + self.center_x
        y = self.zeigerLaenge * cos(radians(180 + self.zeigerPosition)) + self.center_y

        self.leinwand.coords(self.zeiger, self.center_x, self.center_y, x, y)
        self.zeigerPosition += 1
        self.after(5, self.zeigerBewegung)

if __name__ == "__main__":

    root = Tk()
    fenster = mainWindow(10, 190, master=root)
    fenster.pack()
    fenster.mainloop()
die Idee hinter dem Zeiger entspringt übrigens einem Youtubevideo von Ishan Mitra:
Using Python to make a Rotating Line (and implement it in Stopwatch)