Turtle(?) im Canvas

Fragen zu Tkinter.
Antworten
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

Hallo,

Ich bräuchte mal eine Empfehlung:
Es geht darum Punkte auf einem Canvas ´´elegant`` zu verbinden.
Bis her kenne ich nur turtle.
Allerdings weiß ich, dass es noch xturtle und auch noch frog gibt

Hier mal kurz mein Ansatz:

Code: Alles auswählen


import Tkinter as tk
import turtle

class DreieckZeichnen:
    def __init__(self, canvas, cw, ch):
        #cw=int(canvas.cget('width'))
        #ch=int(canvas.cget('heigh'))
        a=(min(cw, ch))/3
        self.canv=canvas
        self.punkte=[]
        self.canvaskoordinaten={} #punkt : (canvx, canvy)
        
        #self.tur=turtle.RawPen(self.canv)
        

        self.grenze=self.canv.create_rectangle(a, a, cw-a,  ch-a, fill='grey95', \
                                          outline='grey95', disabledfill='white')
        
        self.canv.tag_bind(self.grenze, '<Button-1>', self.add_point)
                  


    def add_point(self, event):
         e=event.x, event.y
         p=self.canv.create_oval(e[0]-3, e[1]-3, e[0]+3, e[1]+3, fill='green')
         self.punkte.append(p)
         self.canvaskoordinaten[p]=e
         if len(self.punkte) == 2:
              self.canv.itemconfig(self.grenze, state='disable')
              self.connecting()


    def connecting(self):
               c1=self.canvaskoordinaten[self.punkte[0]]
               c2=self.canvaskoordinaten[self.punkte[1]]
               self.canv.create_line(c1, c2) 



if __name__ == '__main__':
    win=tk.Tk()
    canvas=tk.Canvas(win, width=500, height=500, bg='white')
    canvas.pack(padx=10, pady=10)
    test=DreieckZeichnen(canvas, 500, 500)
    win.mainloop()     
Das ganze heißt DreieckZeichnen, weil da noch ein Punkt hinzukommen soll.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Google weiß aber auch wieder alles: google("tkinter drawing").

Deine Klasse sollte auch keine Klasse sein, sondern eine Funktion. Eine Klasse "Dreieck" mit einer "zeichne"-Methode würde Sinn ergeben.

Und natürlich solltest du kein Deutsch und Englisch mixen, Leerzeichen um die Gleichheitszeichen bei Zuweisungen setzen und vernünftige Namen benutzen. Aber das kennst du ja ;-)

Edit: Oh, natürlich google("tkinter drawing lines")
Das Leben ist wie ein Tennisball.
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

EyDu hat geschrieben:Google weiß aber auch wieder alles: google("tkinter drawing").
Woher nur? Allerdindgs weiß google nicht genau was ich will (ich manchmal auch nicht)
EyDu hat geschrieben: Und natürlich solltest du kein Deutsch und Englisch mixen, Leerzeichen um die Gleichheitszeichen bei Zuweisungen setzen und vernünftige Namen benutzen. Aber das kennst du ja ;-)
Jaa... ich glaub da war mal was - vor gar nicht allzu langer Zeit - ...
:wink:
Ich werde mir PEP8 mal zu Gemüte führen


Das Bisschen, was der Code machen soll, macht er ja auch.
Allerdings würde ich das ganze gerne etwas ´´schöner`` darstellen.
*self.canv.create_line(c1, c2)* würd ich ganz gerne ersetzen.
Stattdessen soll die Strecke mit Turtle (o.ä.) gezeichnet werden.
Dabei liegt gerade mein Problem.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Meinst du mit "elegant" und "schöner" die Eigenschaft "animiert"?
Das Leben ist wie ein Tennisball.
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

EyDu hat geschrieben:Meinst du mit "elegant" und "schöner" die Eigenschaft "animiert"?
Ja, ich denke schon.

Es soll schön anzuschauen sein. Dabei wäre das zu animieren - für mich - das eleganteste. :wink:
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ich habe mal kurz was zusammengeschrieben.

Als Übung empfehle ich ein Dreiecks-Objekt zu bauen. Sinnvoll ist die diese Reihenfolge:

1) Composition mit "class Triange(Composition):"
2) Concurrent mit class Triangle(Concurrent):"
3) PercentageAnimation
4) Function (auch wenn das Dreieck nicht unbedingt geschlossen wird

An den Beispielen unten solltest du dich ganz gut orientieren können. Bevor du mit 1) anfängst solltest du "Circle" verstehen.

Farben und so weiter sollten schnell implementiert sein.

Edit: Man könnte auch noch schöne Transformationen einbauen.
Das Leben ist wie ein Tennisball.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Pascal hat geschrieben:Ich bräuchte mal eine Empfehlung:
Es geht darum Punkte auf einem Canvas ´´elegant`` zu verbinden.
Bis her kenne ich nur turtle.
Allerdings weiß ich, dass es noch xturtle und auch noch frog gibt
Seit Python 2.6 gilt "turtle == xturtle" - das alte turtle ist langweilig; das externe frog-Modul ist eine Alternative zu (x)turtle und funktioniert für alle Python-Versionen ab 2.5. Ich mag das frog-Modul lieber als (x)turtle, aber das ist z.T. Geschmackssache und hängt auch davon ab, was genau man machen will.

Hier mal ein Beispiel, wie man mit dem frog-Modul einen Dreickszeichner umsetzen kann. Das Beispiel zeigt auch, wie einfach es ist, einen Pool (= die frog-Zeichenfläche) in eine Tkinter-Anwendung einzubinden.

Code: Alles auswählen

import Tkinter as tk
from frog import Pool, Frog

class TriangleDrawer(object):

    def __init__(self):
        window = tk.Tk()
        canvas = Pool(window)
        canvas.listen("<Button-1>", self.connect)
        canvas.pack()
        tk.Button(window,text="clear",command=self.clear).pack()
        self.pen = Frog(canvas)
        self.dots = []
        window.mainloop()

    def clear(self):
        """Clear the canvas."""
        self.dots[:] = []
        self.pen.clear()

    def connect(self, event):
        """Draw a dot at mouse position, connect dots, complete to triangle."""
        pos = event["pos"]
        if not self.dots:
            self.pen.jumpto(pos)
        else:
            self.pen.moveto(pos)
        self.pen.dot()
        self.dots.append(pos)
        if len(self.dots) == 3: # complete the triangle
            self.pen.moveto(self.dots[0])
            self.dots[:] = []

TriangleDrawer()
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

Danke numerix :D
Das Programm ist genau das, wonach ich gesucht habe. Allerdings werde ich das noch um einiges erweitern und meinen Bedingungen anpassen.


So bin ich überhaupt erst über frog gestolpert.
Also ein doppeltes Danke an Dich.
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

Allerdings habe ich eine Frage noch dazu:

Was bewirkt objekt in der Zeile class TriangleDrawer(object): ??
(Das gehört zwar eher zu allgemeinen Verständisfragen beim OOP...)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Pascal hat geschrieben:Allerdings werde ich das noch um einiges erweitern und meinen Bedingungen anpassen.
Genauso war das auch gedacht - Inspiration statt Komplettlösung.
Es wäre z.B. nicht schwierig, mittels des fill-Attributs eines frogs, die Dreiecke mit einer Farbe zu füllen oder z.B. beliebige Polygone herzustellen (z.B. durch Verwendung der rechten Maustaste als letztem Klick oder indem man erneut auf den Startpunkt klickt) usw. usw.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Pascal hat geschrieben:Allerdings habe ich eine Frage noch dazu:

Was bewirkt objekt in der Zeile class TriangleDrawer(object): ??
(Das gehört zwar eher zu allgemeinen Verständisfragen beim OOP...)
Die Klasse TriangleDrawer erbt von object und wird dadurch zu einer new-style-Klasse.
MfG
HWK
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

numerix hat geschrieben:
Pascal hat geschrieben:Allerdings werde ich das noch um einiges erweitern und meinen Bedingungen anpassen.
Genauso war das auch gedacht - Inspiration statt Komplettlösung.
Genauso wollte ich es auch haben.
Ich hab ja nichts davon, wenn ich eine Lösung habe und sie nicht verstehe.
Mit den ersten 10 Seiten der frog-Doku bin ich schon durch und ich finde wirklich gefallen daran.
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

auch wenn der Theard etwas alt ist und ich das Problem bereits gelöst hab, habe ich dennoch eine Frage dazu:

Wie kann ich auf einem Canvas "einen Frog" einsetzen? Brauch ich dazu immer einen "Pool" ?!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Pascal hat geschrieben:auch wenn der Theard etwas alt ist und ich das Problem bereits gelöst hab, habe ich dennoch eine Frage dazu:

Wie kann ich auf einem Canvas "einen Frog" einsetzen? Brauch ich dazu immer einen "Pool" ?!
Ja. Falls es dir darum geht, dass du in einem Canvas außer dem Frosch auch Tkinter-Canvas-Methoden einsetzen willst: Das ist kein Problem, weil der Pool nichts anderes ist als ein aufgebohrtes Canvas, d.h. Pool erbt von Canvas und verfügt somit auch über alle normalen Canvas-Methoden. Kurz gesagt: Du kannst an Stelle eines Canvas einen Pool benutzen, kannst damit alles machen, was du mit einem normalen Canvas machen kannst, hast aber zusätzlich noch die Frösche zur Verfügung.
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

Das hab ich auch schon gemerkt, allerdings bleiben kleine Probleme:

Allerdings hat der Pool eine anderes Koordinatensystem als das Canvas.
Und die Parameter im Konstruktor sind auch andere: statt 'bg' gibt es nur 'bgcolor'

Kann man allerdings mit 'config(bg='')' umgehen.

Hauptsächlich scheitere ich am Koordinatensystem. Am schreiben einer Prozedur, die die Koordinaten umwandelt bin ich schon 2 mal gescheitert. :oops:
Wahrscheinlich muss es jetzt beim dritten Versuch klappen :idea:
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Pascal hat geschrieben:Allerdings hat der Pool eine anderes Koordinatensystem als das Canvas.
Ja, stimmt. Die Koordinaten müssen dann umgerechnet werden ...
Pascal hat geschrieben:Und die Parameter im Konstruktor sind auch andere: statt 'bg' gibt es nur 'bgcolor'.
Es gibt nicht "nur bgcolor", sondern es gibt im Unterschied zu einem Canvas, wo man "nur" die Hintergrundfarbe setzen kann, auch die Möglichkeit, ein Hintergrundbild zu verwenden (bgimage).
Antworten