Seite 1 von 2
Verfasst: Sonntag 25. Januar 2004, 23:05
von Voges
Hallo!
Ich hab auch noch mal rumgespielt. Ich muss sagen, die Idee, das Ganze mit einem Dictionary zu managen, gefällt mir immer besser. Ich denke einfach immer noch zuviel in Arrays.
Code: Alles auswählen
from Tkinter import *
root = Tk()
root.title("Abakus")
cv = Canvas(root,height=450,width=650)
cv.pack()
perle = {}
usingIDLE = 0
r = 30 # Durchmesser der Perle
ax = 40 # Perlen-Offset in x-Richtung
ay = 35 # Perlen-Offset in y-Richtung
originx = 10 # Ursprung ...
originy = 50 # ... des Ganzen
### Aktion:Kugel nach oben schieben.
def schieb(xc,yc):
ycNeu = yc-1 # einen hochrücken
if ycNeu == -2 or perle.has_key((xc,ycNeu)): # wenn wir schon ganz oben waren oder dort eine Perle ist ...
ycNeu = yc+1 # einen runterrücken
if ycNeu == 10 or perle.has_key((xc,ycNeu)): # wenn wir schon ganz unten waren oder da auch schon eine Perle ist, ...
return # ... dann gibt es nichts zu tun
xx = originx + xc*ax; yy = originy + ycNeu*ay
cv.coords(perle[(xc,yc)],xx,yy,xx+r,yy+r)
perle[(xc,ycNeu)] = perle[(xc,yc)] # Die Perle bekommt einen neuen Dict-Eintrag entspr. der neuen Position
cv.tag_bind(perle[(xc,ycNeu)],"<Button-1>", lambda e,X=xc,Y=ycNeu:schieb(X,Y)) # nötig, da sich ja y verändert hat
del perle[(xc,yc)] # alten Dict-Eintrag löschen
for x in range(10):
for y in range(10):
xx = originx + x*ax; yy = originy + y*ay
perle[(x,y)]=cv.create_oval(xx,yy,xx+r,yy+r,fill='green',outline='black',)
cv.tag_bind(perle[(x,y)],"<Button-1>", lambda e,X=x,Y=y:schieb(X,Y))
quit = Button(root, text="Beenden", width=6, command=root.destroy)
quit.pack(side="right")
root.focus_force()
if not usingIDLE:
root.mainloop()
Sicherlich noch optimierbar. Irgendwie werde ich das Gefühl nicht los, dass da was redundant ist.
Jan
wow
Verfasst: Montag 26. Januar 2004, 02:04
von niko
Voges wirklich vielen Dank.Sehr interessante Ideen!
Ich habe jetzt fast den ganzen Abend hin und herprogrammiert. So siehts aus.Die Perlen bewegen sich halbwegs so wie ich es will.
zuerstmal wird unterschieden ob die perle die 9te oder sonst eine aus der jeweiligen Reihe ist(der fall es sei die erste mach ich morgen). Danach werden, abhängig davon ob sie in der Liste "verschoben" drin ist oder nicht, die betroffenen Perlen verschoben.
irgendwie will
del verschoben[(xc,yc)] (In der Zeile 16)
nicht so ganz gehen. Es kommt die Fehlermeldung "sequence index must be integer".
gute nacht
Niko
p.s.:im folgenden der neueste code.
Code: Alles auswählen
from Tkinter import *
root = Tk()
root.title("Abakus")
cv = Canvas(root,height=450,width=650)
cv.pack()
perle = {}
usingIDLE = 0
verschoben = []
def schieb(xc,yc):
print perle[(xc,yc)]
print verschoben
if yc == 9:
if perle[(xc,yc)] in verschoben:
cv.coords(perle[(xc,yc)],s+xc*r+xc*r,s+yc*r,s+(xc+1)*r+xc*r,s+(yc+1)*r)
del verschoben[(xc,yc)] ### Löschen aus verschoben
elif perle[(xc,yc)] not in verschoben:
for o in range(yc+1):
print verschoben
verschoben.append(perle[(xc,o)]) ### Der WERT vom Schlüssel
cv.coords(perle[(xc,o)],s+xc*r+xc*r,s+o*r,s+(xc+1)*r+xc*r,s+(o-1)*r)
else:
if perle[(xc,yc+1)] not in verschoben:
#print xc,yc+1,"nicht in verschoben vorhanden"
for t in range(yc+1):
#print xc,t
verschoben.append(perle[(xc,t)]) ### Der WERT vom Schlüssel
cv.coords(perle[(xc,t)],s+xc*r+xc*r,s+t*r,s+(xc+1)*r+xc*r,s+(t-1)*r)
elif perle[(xc,yc-1)] in verschoben:
for z in range(yc,10):
cv.coords(perle[(xc,z)],s+xc*r+xc*r,s+z*r,s+(xc+1)*r+xc*r,s+(z+1)*r)
del verschoben[(xc,z)]
r = 30 # Durchmesser der Perle
s = 32 # Nur um in Zeile 14 nicht über 79 Zeichen zu kommen
for x in range(10):
cv.create_line(47+x*r+x*r,2,47+x*r+x*r,332,width=1)
for x in range(10):
for y in range(10):
q = x*r # Nur um in Zeile 43 nicht über 79 Zeichen zu kommen
perle[(x,y)] = cv.create_oval(s+q+q,s+y*r,s+(x+1)*r+q,s+(y+1)*r,fill='green')
#perle[(x,y)] = [str(x*10+y)]
cv.tag_bind(perle[(x,y)],"<Button-1>", lambda e,X=x,Y=y:schieb(X,Y))
cv.create_text(47+x*r+x*r,352,text = "0")
print perle
quit = Button(root, text="Beenden", width=6, command=root.destroy)
quit.pack(side="right")
root.focus_force()
if not usingIDLE:
root.mainloop()
Verfasst: Montag 26. Januar 2004, 02:12
von wuf
Hallo Niko
Ich habe dir auf der ersten Seite (letzter Eintrag)
noch ein bischen Code zu diesem Thema beigelegt.
Gruss wuf
wuf
Verfasst: Montag 26. Januar 2004, 02:18
von niko
wuf vielen dank!
hab das irgendwie noch übersehen.aber auch keine schlechte Idee.Naja aber nun is spät und Schlaf is Mangelware.In dem Sinne gute Nacht.
Niko
Verfasst: Montag 26. Januar 2004, 03:20
von Dookie
Hi niko,
verschoben ist ja auch eine liste, nimm statt del verschoben[(xc,yc)] einfach verschoben.remove(perle[(xc,yc)])
Gruß
Dookie
Verfasst: Montag 26. Januar 2004, 16:05
von wuf
Hallo Niko
Habe meinen Vorschlag für deinen Abakus
noch ein bisschen erweitert
Linke Maustaste = Schieb rechts
Rechte Maustaste = Schiebe links
Slogan:
"TKINTER and PYTHON is just a FANTASTIC combination!!"
Code: Alles auswählen
from Tkinter import *
def MoveRight(perle):
#~~ Schiebt Objekt nach rechts
print "pos = ", cv.bbox(perle),perle
pos = cv.bbox(perle)
#~~ Kontrolle ob eine Perle im Weg ist oder rechtes Rahmenende
enclosed = cv.find_enclosed(pos[0]+r,pos[1],pos[2]+r,pos[3])
if enclosed == ():
if pos[0] < numcol*s:
cv.move(perle,+s,0)
cv.itemconfigure(perle,fill="darkolivegreen3")
def MoveLeft(perle):
#~~ Schiebt Objekt nach links
pos = cv.bbox(perle)
#~~ Kontrolle ob eine Perle im Weg ist oder linkes Rahmenende
enclosed = cv.find_enclosed(pos[0]-r,pos[1],pos[2]-r,pos[3])
if enclosed == ():
if pos[0] > s:
cv.move(perle,-s,0)
cv.itemconfigure(perle,fill="green")
# ->>----THE-ABACUS-APPLICATION----<<-
if __name__ == '__main__':
root = Tk()
root.title("Abakus-Prototyp")
root['bg'] = 'steelblue3'
cv = Canvas(root,height=450,width=250,bd=4,relief=RAISED,bg='khaki2')
cv.pack()
usingIDLE = 0
r = 30 # Durchmesser der Perle
s = r+2 # Linker Anschlag für Perlen
gap = 6 # Vertikaler Zwischenraum
numcol = 5 # Anzahl Perlen pro Perlenreihe
numrows = 9 # Anzahl der Perlenreihen
dicke = 4 # Dicke der Reihenstange
top = r # Oberes Rahmenende
left = s # Linkes Rahmenende
right = left+(numcol+1)*r+8 #Rahmenende rechts
bottom = top+(numrows*r)+(numrows*gap) # Rahmenende unten
ypos = 0 # Vertikalposition der Reihenstange
yg = 0 # Hilfsvariable
#~~ Erzeugt Stangen
for rod in range(numrows):
ypos = s+(r/2+1)+yg+rod*r
stange = cv.create_line(left,
ypos,
right,
ypos,
fill='darkolivegreen4',
width=dicke)
yg += gap
#~~ Erzeugt Abakusrahmen
rectangle = cv.create_rectangle(left-2,
top-4,
right,bottom+4,
width= 8,
outline='darkgoldenrod4'
)
#~~ Erzeugt die Perlen
for x in range(numcol):
yg = 0
for y in range(numrows):
x0 = s+x*r
y0 = s+yg+y*r
x1 = s+(x+1)*r
y1 = s+yg+(y+1)*r
yg += gap
# Zeichne Perle
object = cv.create_oval(x0,y0,x1,y1,fill='green',outline='darkgreen')
# Event für die Rechtschiebung
cv.tag_bind(object,"<Button-1>",lambda e,Object=object:MoveRight(Object))
# Event für die Linksschiebung
cv.tag_bind(object,"<Button-3>",lambda e,Object=object:MoveLeft(Object))
quit = Button(root, text="Beenden", width=10, command=root.destroy)
quit.pack(side="bottom",pady=4)
if not usingIDLE:
root.mainloop()
Gruss wuf

Verfasst: Montag 26. Januar 2004, 17:32
von NOTZE
@ wuf
is echt gut geworden der Abskus und er funktiniert ziemlich gut.
nich schlecht
Verfasst: Montag 26. Januar 2004, 19:09
von niko
wuf wirklich nicht schlecht.vielen dank.
jedoch will ich das so realisieren, dass, z.b. wenn man auf ne perle in der mitte klickt es auch geht und sich alle über bzw. unter ihr,entsprechend ihrer position, nach oben oder unten mitbewegen.
mein code zur zeit(ich weiß,noch einige überarbeitungen nötig,aber es wird schon):
Code: Alles auswählen
from Tkinter import *
root = Tk()
root.title("Abakus")
cv = Canvas(root,height=450,width=650)
cv.pack()
perle = {}
usingIDLE = 0
verschoben = []
def schieb(xc,yc):
print perle[(xc,yc)]
print verschoben
if yc == 9:
if perle[(xc,yc)] in verschoben:
cv.coords(perle[(xc,yc)],s+xc*r+xc*r,s+yc*r,s+(xc+1)*r+xc*r,s+(yc+1)*r)
verschoben.remove(perle[(xc,yc)])
print verschoben
elif perle[(xc,yc)] not in verschoben:
for o in range(yc+1):
print verschoben
if perle[(xc,o)] not in verschoben:
verschoben.append(perle[(xc,o)]) ### Der WERT vom Schlüssel
cv.coords(perle[(xc,o)],s+xc*r+xc*r,s+o*r,s+(xc+1)*r+xc*r,s+(o-1)*r)
print verschoben
elif yc == 1:
if perle[(xc,yc)] in verschoben:
for u in range(yc,10):
cv.coords(perle[(xc,u)],s+xc*r+xc*r,s+u*r,s+(xc+1)*r+xc*r,s+(u-1)*r)
verschoben.remove(perle[(xc,yc)])
print verschoben
elif perle[(xc,yc)] not in verschoben:
verschoben.append(perle[(xc,yc)]) ### Der WERT vom Schlüssel
cv.coords(perle[(xc,yc)],s+xc*r+xc*r,s+yc*r,s+(xc+1)*r+xc*r,s+(yc+1)*r)
elif yc <> 9:
if perle[(xc,yc+1)] not in verschoben:
#print xc,yc+1,"nicht in verschoben vorhanden"
for t in range(yc+1):
if perle[(xc,t)] not in verschoben:
verschoben.append(perle[(xc,t)]) ### Der WERT vom Schlüssel
cv.coords(perle[(xc,t)],s+xc*r+xc*r,s+t*r,s+(xc+1)*r+xc*r,s+(t-1)*r)
print verschoben
elif perle[(xc,yc-1)] in verschoben:
for z in range(yc,10):
cv.coords(perle[(xc,z)],s+xc*r+xc*r,s+z*r,s+(xc+1)*r+xc*r,s+(z+1)*r)
verschoben.remove(perle[(xc,z)])
print verschoben
r = 30 # Durchmesser der Perle
s = 32 # Nur um in Zeile 14 nicht über 79 Zeichen zu kommen
for x in range(10):
cv.create_line(47+x*r+x*r,2,47+x*r+x*r,332,width=1)
for x in range(10):
for y in range(10):
q = x*r # Nur um in Zeile 43 nicht über 79 Zeichen zu kommen
perle[(x,y)] = cv.create_oval(s+q+q,s+y*r,s+(x+1)*r+q,s+(y+1)*r,fill='green')
#perle[(x,y)] = [str(x*10+y)]
cv.tag_bind(perle[(x,y)],"<Button-1>", lambda e,X=x,Y=y:schieb(X,Y))
cv.create_text(47+x*r+x*r,352,text = "0")
print perle
quit = Button(root, text="Beenden", width=6, command=root.destroy)
quit.pack(side="right")
root.focus_force()
if not usingIDLE:
root.mainloop()
noch was...
Verfasst: Montag 26. Januar 2004, 19:27
von niko
noch was:
was haltet ihr von der zeile 56(noch auskommentiert):
perle[(x,y)] = [str(x*10+y)]
Hier versuche ich dem jeweiligen schlüssel den wert str(x*10+y) zuzuweisen.Das würde, wenns klappt, einiges leichter machen.
Während ich das geschrieben hab,hab ich das nochmal ausprobiert:
jedoch die zeile perle[(x,y)] = [str(x*10+y)] unter die darauffolgende zeile mit cv.tag_bind(.......)... verschoben.außerdem habe ich aus
perle[(x,y)] = [str(x*10+y)] folgendes gemacht:
perle[(x,y)] = [x*10+y]
das sollte praktischer sein.
konkret sieht das so aus(Zeile 56/57):
Code: Alles auswählen
cv.tag_bind(perle[(x,y)],"<Button-1>", lambda e,X=x,Y=y:schieb(X,Y))
perle[(x,y)] = [x*10+y]
Nun stimmen natürlich die ganzen verschiebungsunterscheidungen nicht mehr.Das versuch ich jetz zu korrigieren.
Mfg
Niko
Verfasst: Montag 26. Januar 2004, 22:40
von wuf
Hallo Niko wie läufts?
Habe mein Script auf dein Abakus-Anforderungs-
profil angepasst. Es brauchte ein paar kleinere
Modifikationen in den Schiebemethoden.
Linke Maustaste = Schieb rechts
Rechte Maustaste = Schiebe links
TKINTER & PYTHON is still the BEST!
Code: Alles auswählen
from Tkinter import *
def MoveRight(perle):
#~~ Schiebt Objekte nach rechts
#~~ Hilfsliste deklarieren
auxlist = []
pos = cv.bbox(perle)
#~~ Objektnummern der Perlen auf der rechten Seite
# der angeklickten Perle inklusive der angeklickten.
auxlist = list(cv.find_enclosed(pos[0],pos[1],right,pos[3]))
auxlist.reverse()
for obj in auxlist:
pos = cv.bbox(obj)
enclosed = cv.find_enclosed(pos[0]+r,pos[1],pos[2]+r,pos[3])
if enclosed == ():
if pos[0] < numcol*s:
cv.move(obj,+s,0)
cv.itemconfigure(obj,fill="darkolivegreen3")
return()
def MoveLeft(perle):
#~~ Schiebt Objekte nach links
#~~ Hilfsliste deklarieren
auxlist = []
pos = cv.bbox(perle)
#~~ Objektnummern der Perlen auf der linken Seite
# der angeklickten Perle inklusive der angeklickten.
auxlist = list(cv.find_enclosed(left-1,pos[1],pos[2],pos[3]))
for obj in auxlist:
pos = cv.bbox(obj)
enclosed = cv.find_enclosed(pos[0]-r,pos[1],pos[2]-r,pos[3])
if enclosed == ():
if pos[0] > s:
cv.move(obj,-s,0)
cv.itemconfigure(obj,fill="green")
return()
# ->>----THE-ABACUS-APPLICATION----<<-
if __name__ == '__main__':
root = Tk()
root.title("Abakus-Prototyp-26.01.04 22:30")
root['bg'] = 'steelblue3'
cv = Canvas(root,height=450,width=250,bd=4,relief=RAISED,bg='khaki2')
cv.pack()
usingIDLE = 0
r = 30 # Durchmesser der Perle
s = r+2 # Linker Anschlag für Perlen
gap = 6 # Vertikaler Zwischenraum
numcol = 5 # Anzahl Perlen pro Perlenreihe
numrows = 9 # Anzahl der Perlenreihen
dicke = 4 # Dicke der Reihenstange
top = r # Oberes Rahmenende
left = s # Linkes Rahmenende
right = left+(numcol+1)*r+8 #Rahmenende rechts
bottom = top+(numrows*r)+(numrows*gap) # Rahmenende unten
ypos = 0 # Vertikalposition der Reihenstange
yg = 0 # Hilfsvariable
#~~ Erzeugt Stangen
for rod in range(numrows):
ypos = s+(r/2+1)+yg+rod*r
stange = cv.create_line(left,
ypos,
right+2,
ypos,
fill='darkolivegreen4',
width=dicke)
yg += gap
#~~ Erzeugt Abakusrahmen
rectangle = cv.create_rectangle(left-2,
top-4,
right,bottom+4,
width= 8,
outline='darkgoldenrod4'
)
#~~ Erzeugt die Perlen
for x in range(numcol):
yg = 0
for y in range(numrows):
x0 = s+x*r
y0 = s+yg+y*r
x1 = s+(x+1)*r
y1 = s+yg+(y+1)*r
yg += gap
# Zeichne Perle
object = cv.create_oval(x0,y0,x1,y1,fill='green',outline='darkgreen')
# Event für die Rechtschiebung
cv.tag_bind(object,"<Button-1>",lambda e,Object=object:MoveRight(Object))
# Event für die Linksschiebung
cv.tag_bind(object,"<Button-3>",lambda e,Object=object:MoveLeft(Object))
quit = Button(root, text="Beenden", width=10, command=root.destroy)
quit.pack(side="bottom",pady=4)
if not usingIDLE:
root.mainloop()
Gruss wuf

verrückt..
Verfasst: Montag 26. Januar 2004, 22:44
von niko
also ich werd verrückt. erst jetzt merk ich,dass usingIDLE die ganze zeit auf 0 steht und ich hab die IDLE laufen.schlagartig haben sich in paar problemchen gelöst. ich wage mich fast zu sagen, dass viele Aktionen im Sinne von Perlen verschieben gehen.Natürlich noch nicht alle und langsam werd ich verrückt,weil ich effektiv gesehen die ganze Zeit nur auf einem fleck rumtrample.
naja die aktuellste version:
Code: Alles auswählen
from Tkinter import *
root = Tk()
root.title("Abakus")
cv = Canvas(root,height=450,width=650)
cv.pack()
perle = {}
usingIDLE = 1
verschoben = []
def schieb(xc,yc):
print perle[(xc,yc)]
print verschoben
if yc == 9:
if perle[(xc,yc)] in verschoben:
cv.coords(perle[(xc,yc)],s+xc*r+xc*r,s+yc*r,s+(xc+1)*r+xc*r,s+(yc+1)*r)
verschoben.remove(perle[(xc,yc)])
print verschoben
elif perle[(xc,yc)] not in verschoben:
for o in range(yc+1):
print verschoben
if perle[(xc,o)] not in verschoben:
verschoben.append(perle[(xc,o)]) ### Der WERT vom Schlüssel
cv.coords(perle[(xc,o)],s+xc*r+xc*r,s+o*r,s+(xc+1)*r+xc*r,s+(o-1)*r)
print verschoben
elif yc == 1:
if perle[(xc,yc)] in verschoben:
for u in range(yc,10):
cv.coords(perle[(xc,u)],s+xc*r+xc*r,s+u*r,s+(xc+1)*r+xc*r,s+(u-1)*r)
verschoben.remove(perle[(xc,yc+1)])
print verschoben
elif perle[(xc,yc)] not in verschoben:
verschoben.append(perle[(xc,yc)]) ### Der WERT vom Schlüssel
cv.coords(perle[(xc,yc)],s+xc*r+xc*r,s+yc*r,s+(xc+1)*r+xc*r,s+(yc+1)*r)
elif yc <> 9:
if perle[(xc,yc+1)] not in verschoben:
#print xc,yc+1,"nicht in verschoben vorhanden"
for t in range(yc+1):
if perle[(xc,t)] not in verschoben:
verschoben.append(perle[(xc,t)]) ### Der WERT vom Schlüssel
cv.coords(perle[(xc,t)],s+xc*r+xc*r,s+t*r,s+(xc+1)*r+xc*r,s+(t-1)*r)
print verschoben
elif perle[(xc,yc-1)] in verschoben:
for z in range(yc,10):
cv.coords(perle[(xc,z)],s+xc*r+xc*r,s+z*r,s+(xc+1)*r+xc*r,s+(z+1)*r)
verschoben.remove(perle[(xc,z)])
print verschoben
r = 30 # Durchmesser der Perle
s = 32 # Nur um in Zeile 14 nicht über 79 Zeichen zu kommen
for x in range(10):
cv.create_line(47+x*r+x*r,2,47+x*r+x*r,332,width=1)
for x in range(10):
for y in range(10):
q = x*r # Nur um in Zeile 43 nicht über 79 Zeichen zu kommen
perle[(x,y)] = cv.create_oval(s+q+q,s+y*r,s+(x+1)*r+q,s+(y+1)*r,fill='green')
#perle[(x,y)] = [x*10+y]
cv.tag_bind(perle[(x,y)],"<Button-1>", lambda e,X=x,Y=y:schieb(X,Y))
cv.create_text(47+x*r+x*r,352,text = "0")
print perle
quit = Button(root, text="Beenden", width=6, command=root.destroy)
quit.pack(side="right")
root.focus_force()
if not usingIDLE:
root.mainloop()
Mfg
Niko
hmm
Verfasst: Montag 26. Januar 2004, 22:51
von niko
wuf also wirklich respekt.wie machst du das nur?
was hälst du eigentlich von dem was ich da die ganze zeit "programmiere"?langsam gebe ich vollends die hoffnung auf.
Mfg
Niko
Verfasst: Montag 26. Januar 2004, 23:04
von wuf
Hallo Niko
Erfüllt mein Script deine Anforderungen? Ich
bin nicht sicher ob das Programm eine andere
Perlenanzahl problemlos schnallt. Es muss evt.
noch optimiert werden.
Das Programmieren habe ich auf die gleiche
Art erarbeitet wie du es machst. Oberstes
Gebot ist gebe nie auf! Manchmal braucht es
eine Pause. Ein Bierchen oder ein Spaziergang
und ein neuer Lösungsansatz lässt den Motor
wieder hochfahren
Alles Gute wuf!

Verfasst: Montag 26. Januar 2004, 23:32
von niko
Hi wuf!
Also das Skript ist in dem Sinne wirklich gut. Das problem ist, dass noch n paar Sachen gehen müssen. So z.b., dass wenn alle perlen einer reihe verschoben sind, der Text "Bereinigen!" erscheint. Zudem soll bei jeder Reihe die Anzahl der verschobenen Perlen stehen.d.h wenn in einer Reihe 5 Perlen von 10 verschoben, soll eine 5 neben der Reihe stehen usw.
Ich sehe in all dem nur eine Lösung, wenn ich ne extraListe verschoben benutze, wo alle verschobenen perlen reinkommen.
n paar fragen:
dass bbox die ungefähren koordinaten bstimmt hab ich kapiert, aber was machen cv.find_enclosed und cv.itemconfigure?
jetz weiß ich nicht wo ich weitermachen soll.ob ich elemente von dir übernehme und dass in mein script einstreue oder mein script wegwerfe.
was denkst du?
also ich glaub das wird heut ne lange nacht.
mfg
niko
Verfasst: Dienstag 27. Januar 2004, 00:18
von wuf
Hallo Niko
Besten Dank für deine Antwort!
1. Wo auf der Canvas möchtest du den Text "Bereinigen" an-
gezeigt haben?
2. Die canvas.bbox(Canvas-Objekt-Nr.) Methode gibt dir die genauen Koordinatenpunkte x1,y1,x2,y2
(Eckpunkte des Canvas-Objektes) als Integer (in Pixels) für ein Perle (Canvas-Objekt Oval) zurück.
Die Canvas-Objekt-Nr ist nicht ein hochkomplexe Nummer wie bei Referenzen auf ein übliches Objekt,
sondern eine fortlaufende Integer Nummer, in der Reihenfolge wie die Canvas-Objekte auf der Canvas-
fläche abgelegt wurden.
3. Wenn dir die Integernummer des Canvas-Objektes bekannt ist kannst du mit canvas.itemconfiger(Canvas-
Objekt-Nr.,option) die Eigenschaft des betreffeden Canvas-Objekts verändern. In unserem Falle ist es
die option "fill", welches die Füllfarbe der Perle ist.
4. Mit der Methode canvas.find_enclosed(x1,y1,x2,y2) kannst du herausfinden, welche Canvas-Objekte also
in unserem Falle sind es Perlen sich im Rechteck x1,y1,x2,y2 befinden. Es werden die Integer-Nummern
der Canvas-Objekte in einem Tuple zurückgegeben. Da sich ein Tuple nicht verändern lässt, transferier
ich das Tuple mit der Anweisung list(Tuple) in eine Liste (auxlist im Script). Manipulieren muss ich
den Inhalt dieser Hilfsliste in einem Fall mit der Listenmethode liste.reverse(). Das ist bei der Ver-
schiebung der Perlen nach rechts nötig.
OK das wäre einmal mein erste Antwortpacket
Gruss wuf
achso
Verfasst: Dienstag 27. Januar 2004, 01:55
von niko
Hallo wuf,
also zuerst mal danke, dass du dir solche mühe gibst.
1.wenns geht neben den reihen, da wo die anzahl der verschobenen perlen steht.
etwa so(anzahl der verschobenen perlen):
Code: Alles auswählen
#~~ Erzeugt Stangen
for rod in range(numrows):
ypos = s+(r/2+1)+yg+rod*r
stange = cv.create_line(left,
ypos,
right+2,
ypos,
fill='darkolivegreen4',
width=dicke)
yg += gap
cv.create_text(right+2+8,ypos - dicke/2,text = "0")
Bereinigen einfach neben die betreffende Zeile.
2.verstanden
3.verstanden
nunja also ich hab mir überlegt, dass die Länge (also len) von auxlist jeweils den verschobenen perlen entspricht.jetzt ist nur die frage wie man das konkret umsetzt.
Verfasst: Dienstag 27. Januar 2004, 03:21
von wuf
Hallo Niko
Ich schaute in der Zwischenzeit leider nicht mehr ins
Forum, da ich mit einer Brain storm Phase konfrontiert
war. Ich habe die Abakus-Skript auf deine wünsche an-
gepasst. Niko ich werde deine Fragen später beantworten.
Überigens danke dem Form für das PowerUser-Certificate!
Das Skript ist nicht optimiert. Anregungen von Forumbe-
nutzern für die Verbesserung oder Verfeinerung des Skripts
sind herzlich willkommen.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# Anwendung : The Abacus
# Version : 1.00
# Autor : Fritz Wüst (CH-6048 Horw)
# Datum : 27.01.2004 - 03:00
# Geändert : 27.01.2004 - 03:00
from Tkinter import *
def MoveRight(perle):
#~~ Schiebt Objekte nach rechts
#~~ Hilfsliste deklarieren
auxlist = []
pos = cv.bbox(perle)
#~~ Objektnummern der Perlen auf der rechten Seite
# der angeklickten Perle inklusive der angeklickten.
auxlist = list(cv.find_enclosed(pos[0],pos[1],right,pos[3]))
auxlist.reverse()
for obj in auxlist:
pos = cv.bbox(obj)
enclosed = cv.find_enclosed(pos[0]+r,pos[1],pos[2]+r,pos[3])
if enclosed == ():
if pos[0] < numcol*s:
cv.move(obj,+s,0)
cv.itemconfigure(obj,fill="darkolivegreen3")
UpdateNumOfPearls()
return()
def MoveLeft(perle):
#~~ Schiebt Objekte nach links
#~~ Hilfsliste deklarieren
auxlist = []
pos = cv.bbox(perle)
#~~ Objektnummern der Perlen auf der linken Seite
# der angeklickten Perle inklusive der angeklickten.
auxlist = list(cv.find_enclosed(left-1,pos[1],pos[2],pos[3]))
for obj in auxlist:
pos = cv.bbox(obj)
enclosed = cv.find_enclosed(pos[0]-r,pos[1],pos[2]-r,pos[3])
if enclosed == ():
if pos[0] > s:
cv.move(obj,-s,0)
cv.itemconfigure(obj,fill="green")
UpdateNumOfPearls()
return()
def UpdateNumOfPearls():
#~~ Aktualisiert Texte auf der Canvasfläche
global cleanmessage
yg = 0
cleaning = FALSE
for row in range(numrows):
y0 = s+yg+row*r
y1 = s+yg+(row+1)*r
foundobj = cv.find_enclosed(left-1,y0-1,right,y1+1)
numpearls = 0
numcolor = 'blue'
for obj in foundobj:
fillcolor = cv.itemcget(obj,'fill')
if fillcolor == 'darkolivegreen3':
numpearls += 1
if numpearls == numcol:
cleaning = TRUE
numcolor = 'red'
xpos = right+15
ypos = top+1+yg+r/2+row*r
try:
cv.delete(numlist[row])
except:
pass
numlist[row] = cv.create_text(xpos,ypos,text=numpearls,anchor='w',fill=numcolor,font=font1)
yg += gap
try:
cv.delete(cleanmessage)
except:
pass
if cleaning == TRUE:
xpos = (top+right)/2
ypos = bottom+30
text = cleantext
cleanmessage = cv.create_text(xpos,ypos,text=text,anchor='center',fill='red',font=font2)
return()
# ->>----THE-ABACUS-APPLICATION----<<-
if __name__ == '__main__':
root = Tk()
root.title("Abakus-Prototyp-27.01.04 - 03:00")
root['bg'] = 'steelblue3'
cv = Canvas(root,height=430,width=450,bd=4,relief=RAISED,bg='khaki2')
cv.pack()
usingIDLE = 0
#~~ Listendeklaration für die Anzahl verschobener Perlen
numlist = []
#~~ Zeichensätze
font1 = ('Helvetica', 15, 'bold')
font2 = ('Helvetica', 20, 'bold','underline')
cleantext = 'Bitte Bereinigen!!!'
r = 30 # Durchmesser der Perle
s = r+2 # Linker Anschlag für Perlen
gap = 6 # Vertikaler Zwischenraum
numcol = 10 # Anzahl Perlen pro Perlenreihe
numrows = 9 # Anzahl der Perlenreihen
dicke = 4 # Dicke der Reihenstange
top = r # Oberes Rahmenende
left = s # Linkes Rahmenende
right = left+(numcol+1)*r+8 #Rahmenende rechts
bottom = top+(numrows*r)+(numrows*gap) # Rahmenende unten
ypos = 0 # Vertikalposition der Reihenstange
yg = 0 # Hilfsvariable
#~~ Erzeugt Stangen
for rod in range(numrows):
ypos = s+(r/2+1)+yg+rod*r
stange = cv.create_line(left,
ypos,
right+2,
ypos,
fill='darkolivegreen4',
width=dicke)
yg += gap
#~~ Erzeug Textobjekte für die Anzahl verschobener Perlen
yg = 0
for num in range(numrows):
xpos = right+15
ypos = top+1+yg+r/2+num*r
textobj = cv.create_text(xpos,ypos,text=0,anchor='w',fill='blue',font=font1)
numlist.append(textobj)
yg += gap
#~~ Erzeugt Meldetext-Objekt für "Bereinigen"
xpos = (top+right)/2
ypos = bottom+30
text = ''
cleanmessage = cv.create_text(xpos,ypos,text=text,anchor='center',fill='red',font=font2)
#~~ Erzeugt Abakusrahmen
rectangle = cv.create_rectangle(left-2,
top-4,
right,bottom+4,
width= 8,
outline='darkgoldenrod4'
)
#~~ Erzeugt die Perlen
for x in range(numcol):
yg = 0
for y in range(numrows):
x0 = s+x*r
y0 = s+yg+y*r
x1 = s+(x+1)*r
y1 = s+yg+(y+1)*r
yg += gap
# Zeichne Perle
object = cv.create_oval(x0,y0,x1,y1,fill='green',outline='darkgreen')
# Event für die Rechtschiebung
cv.tag_bind(object,"<Button-1>",lambda e,Object=object:MoveRight(Object))
# Event für die Linksschiebung
cv.tag_bind(object,"<Button-3>",lambda e,Object=object:MoveLeft(Object))
quit = Button(root, text="Beenden", width=10, command=root.destroy)
quit.pack(side="bottom",pady=4)
if not usingIDLE:
root.mainloop()
Gruss wuf

Verfasst: Dienstag 27. Januar 2004, 17:43
von niko
Hi wuf!
Also ich komm nich ausm straunen raus.

das is der wahnsinn.
ich versuche jetz mal dem Abakus das rechnen beizubringen.
Meld mich in ner stunde nochmal.
Mfg
Niko
Verfasst: Dienstag 27. Januar 2004, 20:42
von wuf
Hallo Niko
Gemäss deiner Antwort vom 26.0.2004-23:32
Betreffs deiner Frage ob du mit deinem Skript
weitermachen sollst oder wegwerfen würde ich
sagen unbedingt weitermachen bis es funktionier,
wenn du genügend Zeit hast. Es funktioniert ja
schon einiges ziemlich gut.
Mit einem Programm ist es wie mit einem Wiener-
Schnitzel. Du kannst in 10 verschieden Restaurants
ein Wiener-Schnitzel konsumieren. Jedes wird vom
Geschmack deiner Vorstellung anderst sein. Hat
also vor und Nachteile.
So ist es mit dem Erstellen eines Programms. Du
wirst es nach deiner momentanen Erfahrung zu-
sammenbauen. Wichtig ist es einfach, dass du es
fertig machst bis es läuft. So wirst du am meisten
profitieren. Mein Lösungsansatz weicht evt. von deinem
zu stark ab, dass du Teile davon in dein Skript über-
nehmen kannst. Weil ich habe mich mit den Tkinter-
Canvas-Objekten schon ein wenig herumquälen müssen und
habe und dabei gesehen, dass Tkinter, was die Koordinaten-
Rechnerei anbelang schon vieles selber verwaltet. Darum
habe ich mich bei meiner Lösung mehr auf die Nummern der
einzelnen Canvas-Objekte konzentriert.
Ok Niko
Gruss wuf

Verfasst: Dienstag 27. Januar 2004, 21:26
von niko
hi wuf!
also ich habe mich ziemlich lang damit herumgeschlagen mein script mit deinem zusammenzufügen.aber ich denke da sind die ansätze einfach zu verschieden. so habe ich mich entschieden dein script weiterzuverfolgen, denn es ist halt einfach gut und im grunde ist es auch logischer (und um einiges einfacher), wenn man erstmal weiß wieviele nützliche methoden das Canvas Widget hat. wieso also nicht von anderen lernen?
jetzt hab ich mal probiert die Zahl, die jetzt rechts vom Abakus steht( also alle Zahlen, die ja wenn man sie von oben nach unten anschaut) als die gerade angezeigte Zahl in einem Text (namens sum) zu schreiben. Dies dient der Tatsache, dass ich dann schauen kann, ob der Benutzer, wenn ich ihm ne Aufgabe so wie etwa 15+25 vorsetze und er auf fertig klickt, ob es auch fertig ist.
dass klappt soweit alles.Ich füge jetzt noch den Aufgabensteller in den Script ein.
um die gerade angezeigte zahl zu kriegen habe folgendes gemacht:
Code: Alles auswählen
from Tkinter import *
def MoveRight(perle):
#~~ Schiebt Objekte nach rechts
#~~ Hilfsliste deklarieren
auxlist = []
pos = cv.bbox(perle)
#~~ Objektnummern der Perlen auf der rechten Seite
# der angeklickten Perle inklusive der angeklickten.
auxlist = list(cv.find_enclosed(pos[0],pos[1],right,pos[3]))
auxlist.reverse()
for obj in auxlist:
pos = cv.bbox(obj)
enclosed = cv.find_enclosed(pos[0]+r,pos[1],pos[2]+r,pos[3])
if enclosed == ():
if pos[0] < numcol*s:
cv.move(obj,+s,0)
cv.itemconfigure(obj,fill="darkolivegreen3")
UpdateNumOfPearls()
return()
def MoveLeft(perle):
#~~ Schiebt Objekte nach links
#~~ Hilfsliste deklarieren
auxlist = []
pos = cv.bbox(perle)
#~~ Objektnummern der Perlen auf der linken Seite
# der angeklickten Perle inklusive der angeklickten.
auxlist = list(cv.find_enclosed(left-1,pos[1],pos[2],pos[3]))
for obj in auxlist:
pos = cv.bbox(obj)
enclosed = cv.find_enclosed(pos[0]-r,pos[1],pos[2]-r,pos[3])
if enclosed == ():
if pos[0] > s:
cv.move(obj,-s,0)
cv.itemconfigure(obj,fill="green")
UpdateNumOfPearls()
return()
def UpdateNumOfPearls():
#~~ Aktualisiert Texte auf der Canvasfläche
global cleanmessage
global zusammen
zusammen = ''
yg = 0
cleaning = FALSE
for row in range(numrows):
y0 = s+yg+row*r
y1 = s+yg+(row+1)*r
foundobj = cv.find_enclosed(left-1,y0-1,right,y1+1)
numpearls = 0
numcolor = 'blue'
for obj in foundobj:
fillcolor = cv.itemcget(obj,'fill')
if fillcolor == 'darkolivegreen3':
numpearls += 1
if numpearls == numcol:
cleaning = TRUE
numcolor = 'red'
xpos = right+15
ypos = top+1+yg+r/2+row*r
try:
cv.delete(numlist[row])
except:
pass
numlist[row] = cv.create_text(xpos,ypos,text=numpearls,anchor='w',fill=numcolor,font=font1)
yg += gap
zusammen = zusammen + str(numpearls)
try:
cv.delete(zusammen)
except:
pass
#zusammen = str(numpearls)
sum = cv.create_text(60,420,text=zusammen,font=font1)
try:
cv.delete(cleanmessage)
except:
pass
if cleaning == TRUE:
xpos = (top+right)/2
ypos = bottom+30
text = cleantext
cleanmessage = cv.create_text(xpos,ypos,text=text,anchor='center',fill='red',font=font2)
return()
# ->>----THE-ABACUS-APPLICATION----<<-
root = Tk()
root.title("Abakus-Prototyp-27.01.04 - 03:00")
root['bg'] = 'steelblue3'
cv = Canvas(root,height=430,width=450,bd=4,relief=RAISED,bg='khaki2')
cv.pack()
usingIDLE = 1
#~~ Listendeklaration für die Anzahl verschobener Perlen
numlist = []
#~~ Zeichensätze
font1 = ('Helvetica', 15, 'bold')
font2 = ('Helvetica', 15, 'bold','underline')
cleantext = 'Bitte Bereinigen!!!'
r = 30 # Durchmesser der Perle
s = r+2 # Linker Anschlag für Perlen
gap = 6 # Vertikaler Zwischenraum
numcol = 10 # Anzahl Perlen pro Perlenreihe
numrows = 10 # Anzahl der Perlenreihen
dicke = 4 # Dicke der Reihenstange
top = r # Oberes Rahmenende
left = s # Linkes Rahmenende
right = left+(numcol+1)*r+8 #Rahmenende rechts
bottom = top+(numrows*r)+(numrows*gap) # Rahmenende unten
ypos = 0 # Vertikalposition der Reihenstange
yg = 0 # Hilfsvariable
#~~ Erzeugt Stangen
for rod in range(numrows):
ypos = s+(r/2+1)+yg+rod*r
stange = cv.create_line(left,
ypos,
right+2,
ypos,
fill='darkolivegreen4',
width=dicke)
yg += gap
#~~ Erzeug Textobjekte für die Anzahl verschobener Perlen
yg = 0
for num in range(numrows):
xpos = right+15
ypos = top+1+yg+r/2+num*r
textobj = cv.create_text(xpos,ypos,text=0,anchor='w',fill='blue',font=font1)
numlist.append(textobj)
yg += gap
#~~ Erzeugt Meldetext-Objekt für "Bereinigen"
xpos = (top+right)/2
ypos = bottom+30
text = ''
cleanmessage = cv.create_text(xpos,ypos,text=text,anchor='center',fill='red',font=font2)
#~~ Erzeugt Fenster, dass die dargestellte Zahl anzeigt
sum = cv.create_text(20,420,text=text)
#~~ Erzeugt Abakusrahmen
rectangle = cv.create_rectangle(left-2,
top-4,
right,bottom+4,
width= 8,
outline='darkgoldenrod4'
)
#~~ Erzeugt die Perlen
for x in range(numcol):
yg = 0
for y in range(numrows):
x0 = s+x*r
y0 = s+yg+y*r
x1 = s+(x+1)*r
y1 = s+yg+(y+1)*r
yg += gap
# Zeichne Perle
object = cv.create_oval(x0,y0,x1,y1,fill='green',outline='darkgreen')
# Event für die Rechtschiebung
cv.tag_bind(object,"<Button-1>",lambda e,Object=object:MoveRight(Object))
# Event für die Linksschiebung
cv.tag_bind(object,"<Button-3>",lambda e,Object=object:MoveLeft(Object))
quit = Button(root, text="Beenden", width=10, command=root.destroy)
quit.pack(side="bottom",pady=4)
if not usingIDLE:
root.mainloop()