Seite 1 von 1

´Turtle´ Modul Frage

Verfasst: Freitag 7. März 2008, 21:15
von Markus12
Hi,
ich habe mal eine Frage zum Turtle Modul. Dazu habe ich nichts hier im Forum oder im Internet generell gefunden...

Wenn man auf einem Canvas mit dem Turtle Modul etwas zeichnet, dann muss man die Koordinaten immer ausrechnen, da die linke obere Ecke nicht etwa 0,0 entspricht! Die Mitte des Canvas hat die Koordinaten 0,0, links oben hat also etwas mit -x, y...

nun wollte ich fragen, ob jemand weiß, ob es eine Funktion aus dem Modul gibt, dass trotzdem oben links 0,0 ist?

Viele Grüße Markus :-)

Verfasst: Samstag 8. März 2008, 10:21
von sma
Sieht nicht so aus, denn das einzige Mal, wo schreibend auf das Attribut `_origin` zugegriffen wird, ist in `reset()` und dort wird der Ursprung auf die Fenstermitte gesetzt.

Mein Tipp: Mache dir eine eigene Unterklasse von Turtle (die von Pen und die von RawPen erbt), in der du `reset()` passend überschreibst. Warte, das reicht nicht, die ganzen globalen Funktionen da benutzen das, was `_getpen()` in die globale Variable `_pen` schreibt und das ist nur ein "Pen". Da musst du dann ein Exemplar deiner Turtle-Unterklasse eintragen.

Stefan

Verfasst: Samstag 8. März 2008, 13:09
von Markus12
Danke für die Antwort, aber das ist mir echt zu viel Aufwand.
Ich habe es ja noch nicht einmal alles verstanden, was du meintest, aber bis jetzt habe ich das so gehändelt.

Ist der Canvas 500 auf 500 Pixel groß, und der Benutzer möchte bei Koordinate 100|100 draufklicken, so rechnet das Programm

event.x-250
250-event.y

So hat das immer geklappt. Zum besseren Verständnis hier mal mine Script:

Code: Alles auswählen

from Tkinter import*
from turtle import*

class Paint(object):
    def __init__(self):
        self.var=0
        self.tracer=0
        self.largeness=12
        
        self.fenster=Tk()
        self.fenster.title('Turtle')
        self.fenster.bind('<KeyPress-Delete>', self.delete)
        
        #Gesamter Frame
        self.frame1=Frame(self.fenster, bg='white')
        self.frame1.grid(row=0)
        
        self.coordl=Label(self.frame1, font=('Comic', 15, 'bold'), text='0|0', bg='white', pady=5, width=7)
        self.coordl.grid(row=0, column=0)
        self.coordl.bind('<Double-Button-1>', self.gotoCoord)

        #Textgroesse       
        self.label=Label(self.frame1, font=('Comic', 13, 'bold'), relief='groove', text='Textgroesse  12', bg='whitesmoke', padx=10, width=15)
        self.label.grid(row=0, column=1)
        Button(self.frame1, text='+', relief='flat', bg='lightgreen', padx=3, font=('Times', 10, 'bold'), command=self.plus) \
                            .grid(row=0, column=2)
        Button(self.frame1, text='-', relief='flat', bg='tomato', padx=3, font=('Times', 10, 'bold'), command=self.minus) \
                            .grid(row=0, column=3)

        #Textfarbe
        Label(self.frame1, font=('Comic', 13, 'bold'), relief='groove', text='Textfarbe', bg='whitesmoke', padx=10) .grid(row=0, column=4)
        self.entry=Entry(self.frame1, width=7, font=('Times', 12, 'bold'))
        self.entry.grid(row=0, column=5)
        self.entry.bind('<KeyPress-Return>', self.setColor)

        #Auswahl zum Zeichnen
        self.type=IntVar()
        self.radio1=Radiobutton(self.frame1, font=('Arial', 11, 'bold'), bg='white', text='Type 1', variable=self.type, value=1)
        self.radio1.grid(row=0, column=6)
        self.radio1.select()
        self.radio2=Radiobutton(self.frame1, font=('Arial', 11, 'bold'), bg='white', text='Type 2', variable=self.type, value=2)
        self.radio2.grid(row=0, column=7)
        
        #Canvas, auf dem gezeichnet wird
        self.canvas=Canvas(self.fenster, bg='Lavender', width=700, height=700)
        self.canvas.grid(row=1)
        self.canvas.bind('<Motion>', self.enter)
        self.canvas.bind('<Button-1>', self.draw)
        self.canvas.bind('<Button-2>', self.changeTracer)
        self.canvas.bind('<Button-3>', self.release)
        
        self.pen=RawPen(self.canvas)
        self.pen.width(self.largeness)
        self.pen.tracer(0)
        
    def gotoCoord(self, event):
        self.alternateEntry=Entry(self.frame1, font=('Comic', 14, 'bold'), width=7)
        self.alternateEntry.grid(row=0, column=0)
        self.alternateEntry.bind('<KeyPress-Return>', self._return)
        self.alternateEntry.insert(END, self.coordl['text'])

    def _return(self, event):
        self.coord=self.alternateEntry.get()
        self.alternateEntry.destroy()
        
        
    #Textgroesse einstellen
    def plus(self):
        if self.largeness<30:
            self.largeness+=1
            self.label.config(text='Textgroesse  %s' %str(self.largeness))
            self.pen.width(self.largeness)
        else:
            self.fenster.bell()
            
    def minus(self):
        if self.largeness>1:
            self.largeness-=1
            self.label.config(text='Textgroesse  %s' %str(self.largeness))
            self.pen.width(self.largeness)
        else:
            self.fenster.bell()

    #Textfarbe einstellen
    def setColor(self, event):
        self.color=self.entry.get()
        if self.color=='':
            self.color='black'
        try:
            self.pen.color(self.color)
        except:
            self.fenster.bell()

    #Betritt den Canvas
    def enter(self, event):
        self.coordl.config(text='%3.3i|%3.3i' %(event.x, event.y))
                          
    #Alles auf dem Canvas
    def delete(self, event):
        '''Deletes current painting on canvas'''
        self.pen.clear()
        self.release(None)
        
    def draw(self, event):
        '''Draws a line'''
        if self.var==0:
            self.var=1
            
            self.pen.up()
            self.pen.goto(event.x-350, 350-event.y)
            self.pen.down()
            
        elif self.var:
            self.pen.goto(event.x-350, 350-event.y)

    def release(self, event):
        '''Deletes Connection to the pen'''
        self.var=0

    def changeTracer(self, event):
        '''Changes tracer of the pen'''
        if self.tracer:
            self.pen.tracer(0)
            self.tracer=0
        else:
            self.pen.tracer(1)
            self.tracer=1



        
if __name__=='__main__':
    a=Paint()
Meine nächste Frage direkt auf mein Script bezogen ist:
Wie kann ich es bewerkstelligen, dass der Canvas zum Zeichnen die selbe width hat wie die Navigationsleite oben drüber?!
Jetzt im Script habe ich eine weite und eine Länge angegeben, ich wollte es aber auch so machen, dass der Canvas sich direkt an die Fenstergröße anpasst! Das klappt nicht, wie ich es auch versuche -.-
Wie gesagt soll der Canvas immer so lang wie das Fenster sein, auch hoch und die Navigationsleite soll sich in der breite der Breite des Canvases anpassen...
Wie ist das möglich?

Ich habe jetzt für die Navigationsleite einen Frage genommen (siehe Script) und den gegrided und den Canvas ebenfalls. Daraus habe ich mir erhofft, dass Canvas und leiste die selbe Weite haben, hat aber nicht geklappt.
Ich habe es auch schon mit packen versucht, und dann Argumente angegeben wie ´fill´ und ´expand´ hat aber ebenfalls nicht geklappt :@

Mann, ist das so schwer?

Viele Grüße
Markus :-)

Verfasst: Sonntag 9. März 2008, 12:00
von sma
Markus12 hat geschrieben:Danke für die Antwort, aber das ist mir echt zu viel Aufwand.
...schreibt er und postet einen Berg Code. Irgendwo da steht etwas wie

Code: Alles auswählen

    self.pen = RawPen(canvas)
und da benutzt du eine eigene Klasse, z.B.

Code: Alles auswählen

class MyPen(RawPen):
    def reset(self):
        RawPen.reset(self); self._origin = 0, 0
Stefan

Verfasst: Sonntag 9. März 2008, 16:22
von Markus12
Ok danke dir stefan, jetzt hat es geklappt nach einigen experimentieren =D

Die Funktion ´self.pen._origin=(0, 0)´ bewirkt nicht genau, dass er jetzt wie bei einem Frame oder Canvas zu Punkt 500|500 springt, sondern, dass dieser Mittelpunkt nun bei 0|0 des Canvases liegt.

Um jetzt auf dem Canvas zu Koordinate 500|500 zu springen, muss man die y Koordinate negieren, also muss man sagen -> self.pen.goto(500|-500), weil das wieder wie ein Koordinatensystem aufgebaut ist ;)

Der Unterschied liegt einfach darin, dass dieses Koordinatenkreuz verschoben wurde auf 0|0.

Das hat mir sehr geholfen, danke dir!


Ich habe außerdem keine eigene Klasse dafür angefertigt, sondern einfahc in die Initialisierung meiner Klasse das reingeschrieben^^ Ist viel kürzer und unkomplizierter...

Nochmal mein Quellcode, damit es verständlicher wird:

Code: Alles auswählen


from Tkinter import*
from turtle import*

class Paint(object):
    def __init__(self):
        self.var=0
        self.tracer=0
        self.largeness=12
        
        self.fenster=Tk()
        self.fenster.title('Turtle')
        self.fenster.bind('<KeyPress-Delete>', self.delete)
        
        #Gesamter Frame
        self.frame1=Frame(self.fenster, bg='white')
        self.frame1.grid(row=0)
        
        self.coordl=Label(self.frame1, font=('Comic', 15, 'bold'), text='0|0', bg='white', pady=5, width=7)
        self.coordl.grid(row=0, column=0)
        self.coordl.bind('<Double-Button-1>', self.gotoCoord)

        #Textgroesse       
        self.label=Label(self.frame1, font=('Comic', 13, 'bold'), relief='groove', text='Textgroesse  12', bg='whitesmoke', padx=10, width=15)
        self.label.grid(row=0, column=1)
        Button(self.frame1, text='+', relief='flat', bg='lightgreen', padx=3, font=('Times', 10, 'bold'), command=self.plus) \
                            .grid(row=0, column=2)
        Button(self.frame1, text='-', relief='flat', bg='tomato', padx=3, font=('Times', 10, 'bold'), command=self.minus) \
                            .grid(row=0, column=3)

        #Textfarbe
        Label(self.frame1, font=('Comic', 13, 'bold'), relief='groove', text='Textfarbe', bg='whitesmoke', padx=10) .grid(row=0, column=4)
        self.entry=Entry(self.frame1, width=7, font=('Times', 12, 'bold'))
        self.entry.grid(row=0, column=5)
        self.entry.bind('<KeyPress-Return>', self.setColor)

        #Auswahl zum Zeichnen
        self.type=IntVar()
        self.radio1=Radiobutton(self.frame1, font=('Arial', 11, 'bold'), bg='white', text='Type 1', variable=self.type, value=1)
        self.radio1.grid(row=0, column=6)
        self.radio1.select()
        self.radio2=Radiobutton(self.frame1, font=('Arial', 11, 'bold'), bg='white', text='Type 2', variable=self.type, value=2)
        self.radio2.grid(row=0, column=7)
        
        #Canvas, auf dem gezeichnet wird
        self.canvas=Canvas(self.fenster, bg='Lavender', width=700, height=700)
        self.canvas.grid(row=1)
        self.canvas.bind('<Motion>', self.enter)
        self.canvas.bind('<Button-1>', self.draw)
        self.canvas.bind('<Button-2>', self.changeTracer)
        self.canvas.bind('<Button-3>', self.release)
        
        self.pen=RawPen(self.canvas)
        self.pen.width(self.largeness)
        self.pen._origin=(0, 0) ######### <- Änderung!!
        self.pen.tracer(0)
        
    def gotoCoord(self, event):
        self.alternateEntry=Entry(self.frame1, font=('Comic', 14, 'bold'), width=7)
        self.alternateEntry.grid(row=0, column=0)
        self.alternateEntry.bind('<KeyPress-Return>', self._return)
        self.alternateEntry.insert(END, self.coordl['text'])

    def _return(self, event):
        self.coord=self.alternateEntry.get()
        self.alternateEntry.destroy()
        
        
    #Textgroesse einstellen
    def plus(self):
        if self.largeness<30:
            self.largeness+=1
            self.label.config(text='Textgroesse  %s' %str(self.largeness))
            self.pen.width(self.largeness)
        else:
            self.fenster.bell()
            
    def minus(self):
        if self.largeness>1:
            self.largeness-=1
            self.label.config(text='Textgroesse  %s' %str(self.largeness))
            self.pen.width(self.largeness)
        else:
            self.fenster.bell()

    #Textfarbe einstellen
    def setColor(self, event):
        self.color=self.entry.get()
        if self.color=='':
            self.color='black'
        try:
            self.pen.color(self.color)
        except:
            self.fenster.bell()

    #Betritt den Canvas
    def enter(self, event):
        self.coordl.config(text='%3.3i|%3.3i' %(event.x, event.y))
                          
    #Alles auf dem Canvas
    def delete(self, event):
        '''Deletes current painting on canvas'''
        self.pen.clear()
        self.release(None)
        
    def draw(self, event):
        '''Draws a line'''
        if self.var==0:
            self.var=1
            
            self.pen.up()
            self.pen.goto(event.x, -event.y) ######### <- Änderung!!
            #self.pen.goto(event.x-350, 350-event.y)
            self.pen.down()
            
        elif self.var:
            self.pen.goto(event.x, -event.y) ######### <- Änderung!!
            #self.pen.goto(event.x-350, 350-event.y)

    def release(self, event):
        '''Deletes Connection to the pen'''
        self.var=0

    def changeTracer(self, event):
        '''Changes tracer of the pen'''
        if self.tracer:
            self.pen.tracer(0)
            self.tracer=0
        else:
            self.pen.tracer(1)
            self.tracer=1


        
if __name__=='__main__':
    a=Paint()