Ausgabe von Objekten ist nicht wie gewünscht

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Kobra23759
User
Beiträge: 61
Registriert: Donnerstag 9. April 2020, 18:47

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()
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

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()
Benutzeravatar
ThomasL
User
Beiträge: 1379
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Warum benutzt du Tkinter um Striche zu zeichnen?
Dafür nimmt man Pygame.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

@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.
Kobra23759
User
Beiträge: 61
Registriert: Donnerstag 9. April 2020, 18:47

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()
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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`.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten