Zeichnen ueber grosse Pixel

Fragen zu Tkinter.
Antworten
ichagx03
User
Beiträge: 10
Registriert: Mittwoch 10. Januar 2007, 23:59

Donnerstag 23. August 2007, 21:13

Hallo, ich habe ein Gitter mit Quadraten. nun möchte ich das wenn ich die maus gedrückt halte und über dieses Gitter fahre das sich dann die Hintergrundfarbe der Quader ändert (über die man gerade fährt.)

ich bin schon so weit gekommen, habe aber das problem das es nur mit klicken geht, nicht aber mit fahren und drücken:

Code: Alles auswählen

from Tkinter import *
class Raster(object):
    def __init__(self):
        self.press1 = 0
        liste = [(x,y) for x in range(18) for y in range(9)]
        self.fenster = Tk()
        for (i,j) in liste:
            l= Canvas(self.fenster,width=20, height=20, bg="white",relief = "ridge",bd =1)
            l.grid(column=i, row=j)
            l.bind(sequence='<Button-1>', 
                func=self.linksklickAb)
            l.bind(sequence='<ButtonRelease-1>', 
                func=self.linksklickAuf)
            l.bind(sequence='<Motion>', 
                func=self.malen)
        self.fenster.mainloop() 
    def linksklickAuf(self, event):
        self.press1 = 0  
    def linksklickAb(self, event):
        self.press1 = 1
    def malen(self,event):
        if self.press1:
            event.widget.config(bg='red')
        else:
            event.widget.config(bg='white')
r = Raster()
Weiss jemand wie ich das angehen könnte?
Vielen dank schonmal.
Benutzeravatar
Mawilo
User
Beiträge: 446
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Donnerstag 23. August 2007, 21:34

Hallo ichagx03,

binde mal Enter (für den Eintritt in das Widget) und Leave (Verlassen des Widgets) an das Objekt und rufe so die Funktionen auf.

Code: Alles auswählen

l.bind('<Enter>', self.enter)
l.bind('<Leave>', self.leave)
Mawilo
ichagx03
User
Beiträge: 10
Registriert: Mittwoch 10. Januar 2007, 23:59

Donnerstag 23. August 2007, 21:55

geht auch nicht.

Das problem ist das er gar nichts meh macht wenn ich die Mausgedrückt halte.
Auch wenn ich nur <Enter> benutze geht es solange ich die Maustastegedrückt halte,
Evtl. würde es mit einem Thread gehen. ich weiss da aber nicht recht wie umsetzen.
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Donnerstag 23. August 2007, 23:13

Hallo,

eventuell so?

Code: Alles auswählen

from Tkinter import * 
class Raster(object): 
    def __init__(self): 
        self.press1 = 0 
        liste = [(x,y) for x in range(18) for y in range(9)] 
        self.fenster = Tk() 
        for (i,j) in liste: 
            l= Canvas(self.fenster,width=20, height=20, bg="white",relief = "ridge",bd =1) 
            l.grid(column=i, row=j) 
            
            #~ l.bind(sequence='<Button-1>', 
                #~ func=self.linksklickAb) 
            #~ l.bind(sequence='<ButtonRelease-1>', 
                #~ func=self.linksklickAuf) 
            #~ l.bind(sequence='<Motion>', 
                #~ func=self.malen) 
                
            l.bind('<Enter>',  self.onEnter)
            l.bind('<Leave>', self.onLeave)
            
        self.fenster.mainloop() 
        
    def linksklickAuf(self, event): 
        self.press1 = 0  
    def linksklickAb(self, event): 
        self.press1 = 1 
    def malen(self,event): 
        if self.press1: 
            event.widget.config(bg='red') 
        else: 
            event.widget.config(bg='white')
            
    def onEnter(self, event):
        event.widget['bg'] = 'blue'
    def onLeave(self, event):
        event.widget['bg'] = 'red'
        
r = Raster()
Gruss
pyStyler
ichagx03
User
Beiträge: 10
Registriert: Mittwoch 10. Januar 2007, 23:59

Freitag 24. August 2007, 16:53

die gehts schon aber nicht so wie ich es möchte ;)
ich will das es nur mahlt wenn die maus gedrückt ist.
deins mahlt immer, ausser die maus ist gedrückt, es müsste gerade umgekehrt sein.
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Samstag 25. August 2007, 16:41

Ich habs auch mal versucht, hat aber nix gebracht.
Es gibt wohl wirklich eine Blockierung oder so. Ich hab selbst grad ein ähnliches Problem, das ich mir nicht ganz erklären kann...
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Sonntag 26. August 2007, 12:46

Es scheint so zu sein, dass die Events <Enter>, <Leave> und <Motion> nicht mit gedrückter Maustaste funktionieren. Man müsste anderes Events wie für Drag-and-Drop haben. Dazu gibt es scheinbar eine Erweiterung: TkDND (http://sourceforge.net/projects/tkdnd/). Hier gibt es z.B. die Events <DropEnter> und <DropLeave>, die wohl genau das gewünschte bieten. Ob und wie Du das in Deine Anwendung einbauen kannst, musst du selbst mal probieren.
MfG
HWK
ichagx03
User
Beiträge: 10
Registriert: Mittwoch 10. Januar 2007, 23:59

Sonntag 26. August 2007, 18:37

ich hab dieses modul mal angeschaut. wenn mich aber nicht alles täuscht ist dieses Modul dazu da etwas von einem Fenster ins andere zu ziehen (drag and drop). dies löst aber leider nicht mein Problem. weil drag and drop kan ich schon machen. nicht aber das er reagiert wenn ich schon mit gedrückter maustaste komme (und das müsste er ja in meinem Fall).
BlackJack

Sonntag 26. August 2007, 19:08

Bei "D'n'D" gibt es doch aber Events die beim "Drag"en, also ziehen mit gedrückter Maustaste über ein Widget erzeugt werden. Das ist doch was Du brauchst.
ichagx03
User
Beiträge: 10
Registriert: Mittwoch 10. Januar 2007, 23:59

Sonntag 26. August 2007, 20:23

Ist möglich ich hab es aber nicht geschafft.
Hier ist das Beispiel script:

Code: Alles auswählen

# ----------------------------------------------------------------------
# The rest is here for testing and demonstration purposes only!
import Tkinter
from Tkdnd import *

class Icon:
    def __init__(self, name):
        self.name = name
        self.canvas = self.label = self.id = None

    def attach(self, canvas, x=10, y=10):
        if canvas is self.canvas:
            self.canvas.coords(self.id, x, y)
            return
        if self.canvas:
            self.detach()
        if not canvas:
            return
        label = Tkinter.Label(canvas, text=self.name,
                              borderwidth=2, relief="raised")
        id = canvas.create_window(x, y, window=label, anchor="nw")
        self.canvas = canvas
        self.label = label
        self.id = id
        label.bind("<ButtonPress>", self.press)

    def detach(self):
        canvas = self.canvas
        if not canvas:
            return
        id = self.id
        label = self.label
        self.canvas = self.label = self.id = None
        canvas.delete(id)
        label.destroy()

    def press(self, event):
        if dnd_start(self, event):
            # where the pointer is relative to the label widget:
            self.x_off = event.x
            self.y_off = event.y
            # where the widget is relative to the canvas:
            self.x_orig, self.y_orig = self.canvas.coords(self.id)

    def move(self, event):
        x, y = self.where(self.canvas, event)
        self.canvas.coords(self.id, x, y)

    def putback(self):
        self.canvas.coords(self.id, self.x_orig, self.y_orig)

    def where(self, canvas, event):
        # where the corner of the canvas is relative to the screen:
        x_org = canvas.winfo_rootx()
        y_org = canvas.winfo_rooty()
        # where the pointer is relative to the canvas widget:
        x = event.x_root - x_org
        y = event.y_root - y_org
        # compensate for initial pointer offset
        return x - self.x_off, y - self.y_off

    def dnd_end(self, target, event):
        pass

class Tester:

    def __init__(self, root):
        self.top = Tkinter.Toplevel(root)
        self.canvas = Tkinter.Canvas(self.top, width=100, height=100)
        self.canvas.pack(fill="both", expand=1)
        self.canvas.dnd_accept = self.dnd_accept

    def dnd_accept(self, source, event):
        return self

    def dnd_enter(self, source, event):
        self.canvas.focus_set() # Show highlight border
        x, y = source.where(self.canvas, event)
        x1, y1, x2, y2 = source.canvas.bbox(source.id)
        dx, dy = x2-x1, y2-y1
        self.dndid = self.canvas.create_rectangle(x, y, x+dx, y+dy)
        self.dnd_motion(source, event)

    def dnd_motion(self, source, event):
        x, y = source.where(self.canvas, event)
        x1, y1, x2, y2 = self.canvas.bbox(self.dndid)
        self.canvas.move(self.dndid, x-x1, y-y1)

    def dnd_leave(self, source, event):
        self.top.focus_set() # Hide highlight border
        self.canvas.delete(self.dndid)
        self.dndid = None

    def dnd_commit(self, source, event):
        self.dnd_leave(source, event)
        x, y = source.where(self.canvas, event)
        source.attach(self.canvas, x, y)

def test():
    root = Tkinter.Tk()
    root.geometry("+1+1")
    Tkinter.Button(command=root.quit, text="Quit").pack()
    t1 = Tester(root)
    t1.top.geometry("+1+60")
    t2 = Tester(root)
    t2.top.geometry("+120+60")
    t3 = Tester(root)
    t3.top.geometry("+240+60")
    i1 = Icon("ICON1")
    i2 = Icon("ICON2")
    i3 = Icon("ICON3")
    i1.attach(t1.canvas)
    i2.attach(t2.canvas)
    i3.attach(t3.canvas)
    root.mainloop()

if __name__ == '__main__':
    test()
Kann mir jemand sagen wie ich dieses abändern müsste damit es geht?
Antworten