Seite 1 von 1
Ausgabe von Objekten ist nicht wie gewünscht
Verfasst: Mittwoch 14. Oktober 2020, 10:36
von Kobra23759
Hallo ,
ich möchte 2 Vektoren mittels Objekte erzeugen. Beide sollen vom Startpunkt 0,0 starten.
Warum hat der zweite Vektor einen y-Versatz. Über eine konstruktive Hilfe würde ich mich riesig freuen. Das Programm wurde mit Jupyter erstellt
from tkinter import *
fenster=Tk()
class Vektor():
def __init__(self,a1,a2):
self.x1=a1 ; self.x2=a2
self.zeichner=Canvas(fenster)
self.zeichner.pack()
def gib_vektor(self):
self.zeichner.create_line(0,0,self.x1,self.x2)
a=Vektor(50,50) ; a.gib_vektor()
b=Vektor(40,120) ; b.gib_vektor()
mainloop()
Re: Ausgabe von Objekten ist nicht wie gewünscht
Verfasst: Mittwoch 14. Oktober 2020, 11:11
von __blackjack__
@Kobra23759: Da fehlen Leerzeichen und -zeilen und man verwendet kein ``;`` sondern schreibt jede Anweisung in eine eigene Zeile.
Sternchen-Importe sind Böse™. Da holt man sich gerade bei `tkinter` fast 200 Namen ins Modul von denen nur ein kleiner Bruchteil verwendet wird. Auch Namen die gar nicht in `tkinter` definiert werden, sondern ihrerseits von woanders importiert werden. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.
Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Daraus folgt dann, das Funktionen und Methoden alles was sie ausser Konstanten benötigen, als Argument(e) übergeben bekommen. Die `Vektor.__init__()` braucht `fenster`, das muss also als Argument übergeben werden.
Warum heissen die Argumente die an die Attribute `x1` und `x2` gebunden werden `a1` und `a2`? Das ist verwirrend. Zudem sind das ja gar keine zwei X-Werte sondern ein X- und ein Y-Wert. Ohne Nummern.
`gib_vektor()` ist ein inhaltlich komischer Name. Da wird nichts ”gegeben”, da wird eine Linie gezeichnet.
Zwischenstand:
Code: Alles auswählen
#!/usr/bin/env python3
import tkinter as tk
class Vektor:
def __init__(self, master, x, y):
self.x = x
self.y = y
self.zeichner = tk.Canvas(master)
self.zeichner.pack()
def erstelle_linie(self):
self.zeichner.create_line(0, 0, self.x, self.y)
def main():
fenster = tk.Tk()
Vektor(fenster, 50, 50).erstelle_linie()
Vektor(fenster, 40, 120).erstelle_linie()
fenster.mainloop()
if __name__ == "__main__":
main()
Der zweite Vektor hat keinen Y-Versatz. Die beiden Vektoren werden nicht auf dem gleichen `Canvas`-Objekt gezeichnet, weil Du für jedes `Vektor`-Objekt ein eigenes `Canvas`-Objekt erstellst. Und diese beiden Zeichenflächen zeigst Du dann im gleichen Fenster untereinander an.
Re: Ausgabe von Objekten ist nicht wie gewünscht
Verfasst: Mittwoch 14. Oktober 2020, 11:13
von Sirius3
Du zeichnest ja keine zwei Vektoren (aka Linien), sondern Du erzeugst zwei Canvas und in die zeichnest Du jeweils eine Linie.
Zum Code: keine *-Importe, tkinter wird üblicherweise als `import tkinter as tk` importiert und alle Namen per tk.xy angesprochen.
Pro Zeile steht nur eine Anweisung. Vergiss am besten gleich wieder, dass ; überhaupt existiert.
gib_vektor ist ein komischer Name für erzeuge_eine_linie. Die Methode gibt ja gar nichts zurück. Da man so einen Vektor nur einmal erzeugen muß, wäre das Erzeugen der Linie in __init__ besser aufgehoben.
Damit ist die Klasse etwas überflüssig, aber vielleicht kommt ja noch mehr dazu:
Warum nennst Du x1 und x2 a1 und a2?
Code: Alles auswählen
import tkinter as tk
class Vektor():
def __init__(self, canvas, x1, x2):
self.canvas = canvas
self.line = canvas.create_line(0, 0, x1, x2)
def main():
root = tk.Tk()
canvas = tk.Canvas(root)
canvas.pack()
a = Vektor(canvas, 50, 50)
b = Vektor(canvas, 40, 120)
root.mainloop()
if __name__ == '__main__':
main()
Re: Ausgabe von Objekten ist nicht wie gewünscht
Verfasst: Mittwoch 14. Oktober 2020, 19:14
von ThomasL
Warum benutzt du Tkinter um Striche zu zeichnen?
Dafür nimmt man Pygame.
Re: Ausgabe von Objekten ist nicht wie gewünscht
Verfasst: Mittwoch 14. Oktober 2020, 19:36
von Sirius3
@ThomasL: aus der vorhandenen Information halte ich es für gewagt, Pygame mit dieser Ausschließlichkeit zu empfehlen. Ich würde sogar soweit gehen, dass man für zwei Striche kein Pygame benutzt.
Re: Ausgabe von Objekten ist nicht wie gewünscht
Verfasst: Freitag 16. Oktober 2020, 17:11
von Kobra23759
Danke für die erklärenden Worte
Vielleicht kannst du noch mal über etwas anderen schauen
ich möchte ein fenster.py mit
pyinstaller --onfile fenster.py compilieren
fenster.py:
import tkinter as tk
fenster1=tk.Tk()
fenster1.mainloop()
dies hat auch geklappt, nachdem ich statt mainloop() ==> fenster1.mainloop() geschrieben habe.
Warum???
ein etwas komplexeres Programm ließ sich nicht compilieren.
Über eine wieder so ausführliche Antwort würde ich mich freuen
fenster1.py:
import tkinter as tk
def CloseWin():
input_win.destroy()
output_win.destroy() #Schließt Fenster
input_win=tk.Tk()
output_win=tk.Tk()
output_win.configure(bg="yellow")
knopf_close1=tk.Button(input_win,text="Close",command=CloseWin)
knopf_close1.pack()
output_win.mainloop()
Re: Ausgabe von Objekten ist nicht wie gewünscht
Verfasst: Freitag 16. Oktober 2020, 17:54
von __blackjack__
@Kobra23759: Zum Fall 1: Natürlich funktioniert einfach nur `mainloop()` nicht, denn diese Funktion gibt es ja gar nicht. Man kann keine nichtexistierenden Funktionen aufrufen. Was sollte da auch passieren? Soll Python raten was man stattdessen gemeint haben könnte?
Zum Fall 2: Es darf nur *ein* `Tk`-Objekt geben. Das ist *das* Hauptfenster. Für zusätzliche Fenster ist `tkinter.Toplevel`.