Programm läuft mit Methode nicht und Variable übertragen

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
Kahnbein.Kai
User
Beiträge: 104
Registriert: Mittwoch 24. Juni 2015, 14:12
Wohnort: Bochum

Guten Abend,
ich möchte ein Programm schreiben mit dem man auf Bilder Maße abgreifen kann. Dafür muss man eine Linie zeichnen und die bekannte Länge festlegen.
Das ganze soll mit tkinter realisiert werden. Mehr als die Hälfte meines Codes ist zusammengeklaut, daher die Mischung von Deutsch und Englisch.
Ich wollte damit anfangen das ich die Länge berechne zwsichen start x und y und ende x und y. Diese Werte werden können bei der Methode release ausgegeben werden.

1. Problem:
Füge ich einen Button hinzu mit der die Methode

Code: Alles auswählen

command=self.bekannteLaenge
triggern soll, funktioniert das Programm nicht mehr. Es kommt folgende Fehlermeldung:

Code: Alles auswählen

AttributeError: '_tkinter.tkapp' object has no attribute 'bekannteLaenge' 
dabei habe ich eine Methode

Code: Alles auswählen

        def bekannteLaenge(self):
            print(coordsAusgeben)
Das Problem hatte ich damals in der Uni schon, ich verstehe nicht wie ich die Variable

Code: Alles auswählen

{'x': 251, 'y': 219, 'x2': 349, 'y2': 295}
von der Methode release benutzen kann.
Ich würde es jetzt so versuchen:
1. release Methode mit return self.coords
2. Variabelcoords Ausgeben an Methodenaufruf coordsAusgeben = self.canvas.bind('<ButtonRelease-1>', release)
3. In der Methode bekannteLaenge(self) auf die Variable coordsAuslesen zugreifen.

Aber dafür muss erstmal das Programm laufen.

Hier ist der Quellcode:

Code: Alles auswählen

import tkinter as tk


class Programm(tk.Tk):
    
    def __init__(self):
        super().__init__()
        
        self.title("Leeres Programm")
        
        self.cbutton = tk.Button(self, text="Laenge festlegen", command=self.bekannteLaenge)
        self.cbutton.pack()
        
        self.canvas = tk.Canvas(self, bg="white", width=600, height=400)
        self.canvas.pack()
        
        self.coords = {"x":0,"y":0,"x2":0,"y2":0}
        self.final=[]
        self.lines = []
        
        def bekannteLaenge(self):
            print(coordsAusgeben)
            

        def click(e):
            self.coords["x"] = e.x
            self.coords["y"] = e.y
            self.lines.append(self.canvas.create_line(self.coords["x"],self.coords["y"],self.coords["x"],self.coords["y"]))
            
            
        def release(l):
            lis=[] 
            lis.append(self.coords["x"]);lis.append(self.coords["y"]);lis.append(self.coords["x2"]);lis.append(self.coords["x2"]) 
            self.final.append(lis)
            print(self.coords)
            return self.coords
            

        def drag(e):
            self.coords["x2"] = e.x
            self.coords["y2"] = e.y
            self.canvas.coords(self.lines[-1], self.coords["x"],self.coords["y"],self.coords["x2"],self.coords["y2"])
            

        self.canvas.bind("<ButtonPress-1>", click)
        self.canvas.bind("<B1-Motion>", drag) 
        coordsAusgeben  = self.canvas.bind('<ButtonRelease-1>', release)
        
    
def main():
    root = Programm()
    root.mainloop()
    
if __name__ == "__main__":
    main()
Vielen Dank im Voraus
Kai
Benutzeravatar
__blackjack__
User
Beiträge: 13268
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Die Klasse hat genau *eine* Methode — die `__init__()`. *Da drin* hast Du ein paar lokale Funktionen definiert, die wohl eigentlich als Methoden auf die Klasse sollten. Einrückung ist wichtig in Python.
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
Kahnbein.Kai
User
Beiträge: 104
Registriert: Mittwoch 24. Juni 2015, 14:12
Wohnort: Bochum

Jawoll, da habe ich den Wald vor lauter Bäumen nicht gesehen. Ich habe mich auch schon gewundert warum Click, Release und Drag ohne self in der Parameterliste funktionieren.
So habe ich es bis jezt:

Code: Alles auswählen

import tkinter as tk
import math

class Programm(tk.Tk):
    
    def __init__(self):
        super().__init__()
        
        self.title("Leeres Programm")
        
        self.canvas = tk.Canvas(self, bg="white", width=600, height=400)
        self.canvas.pack()
        
        self.cbutton = tk.Button(self, text="Laenge festlegen", command=self.bekannteLaenge)
        self.cbutton.pack()
        
        self.coords = {"x":0,"y":0,"x2":0,"y2":0}
        self.final=[]
        self.lines = []
        self.canvas.bind("<ButtonPress-1>", self.click)
        self.canvas.bind("<B1-Motion>", self.drag)
        self.canvas.bind('<ButtonRelease-1>', self.release)
        
    def bekannteLaenge(self):
        print(self.coords.get("x"))
        print(self.coords.get("y"))
        print(self.coords.get("x2"))
        print(self.coords.get("y2"))
        dx = self.coords.get("x")-self.coords.get("x2")
        dy = self.coords.get("y")-self.coords.get("y2")   
        dl = math.sqrt(dx*dx+dy*dy)
        print(dx)
        print(dy)
        print(dl)         

    def click(self,e):
        self.coords["x"] = e.x
        self.coords["y"] = e.y
        self.lines.append(self.canvas.create_line(self.coords["x"],self.coords["y"],self.coords["x"],self.coords["y"]))
            
            
    def release(self,l):
        lis=[] 
        lis.append(self.coords["x"]);lis.append(self.coords["y"]);lis.append(self.coords["x2"]);lis.append(self.coords["x2"]) 
        self.final.append(lis)
        print(self.coords)
            
    def drag(self,e):
        self.coords["x2"] = e.x
        self.coords["y2"] = e.y
        self.canvas.coords(self.lines[-1], self.coords["x"],self.coords["y"],self.coords["x2"],self.coords["y2"])
            

        
    
def main():
    root = Programm()
    root.mainloop()
    
if __name__ == "__main__":
    main()
Vielen Dank für die schnelle Hilfe
Gruß Kai
Antworten