bind und Mausklicks

Fragen zu Tkinter.
niko
User
Beiträge: 24
Registriert: Freitag 23. Januar 2004, 20:53

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.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

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 :wink:
Take it easy Mates!
niko
User
Beiträge: 24
Registriert: Freitag 23. Januar 2004, 20:53

Hi wuf!
Also ich komm nich ausm straunen raus. :shock: das is der wahnsinn.

ich versuche jetz mal dem Abakus das rechnen beizubringen.
Meld mich in ner stunde nochmal.
Mfg
Niko
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

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 :wink:
Take it easy Mates!
niko
User
Beiträge: 24
Registriert: Freitag 23. Januar 2004, 20:53

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? :wink:
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()
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Niko

Habe dein Skript mit den Modifikationen
ausprobiert. Frage hast du keine Probleme
mit der Anzeige von "sum" ?

Gruss wuf
niko
User
Beiträge: 24
Registriert: Freitag 23. Januar 2004, 20:53

also ich hab es geschafft den aufgabensteller einzubauen.man klickt auf "neue aufgabe" ,rechnet das ergebnis mit dem abakus aus und lässt sich mittels "Nachprüfen zeigen ob es richtig ist oder nicht.
der code:

Code: Alles auswählen

from Tkinter import * 
import random

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(sum)
   #except:
   #   pass
   #sum = cv.create_text(60,420,text = zusammen, font = font1)
   print zusammen
   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()

def rechnung():
    global falsch, richtig # falsch und richtig werden in dieser definition verwendet
    z1 = random.randint(1.0,50.0)
    z2 = random.randint(1.0,50.0)
    op = random.randint(0,2) # die für die rechenoperation 3 zahlen weredn per zufall ausgesucht
    oplist = ['+', '-', '*'] # liste, aus der das rechenzeichen gewählt wird; bei 0 is das rechenzeicen + usw.
    global erg # das ergebnis wird global gemacht d.h ist für das ganze programm benutzbar
    if op == 0: erg = z1 + z2 # berechnet erg
    if op == 1: erg = z1 - z2 # berechnet erg
    if op == 2: erg = z1 * z2 # berechnet erg
    #if op == 3: erg = z1 / z2 # berechnet erg
    ausgabe["text"] = (z1, oplist[op] , z2)# das rechenzeichen aus der liste verbindet bei der ausgabe die beiden zahlen
    antwort["text"] = "" # das antwort label (das richtig oder falsch anzeigt) wird geleert
    #reset() ### WICHTIG:HIER SOLLTE ALLES VON ANFANG AN STARTEN!!!WIRKLICHES RESET,NICHT STATISTIK
    
def vergleich():
    global falsch, richtig # falsch und richtig werden in dieser definition verwendet
    eing = zusammen # die eingabe vom benutzer wird einer variablen zugeordnet
    if int(zusammen) == erg : # wenn die eingabe gleich dem ergebniss ist
       antwort["text"]= "richtig" # dann wird im antwort label "richtig" ausgegeben
       #richtig = richtig + 1 # in dem zähler wird zu richtig eine 1 addiert
       #eingabe_zeile.delete(0, END) # dann wird die eingabe des users gelöscht
    else: # andernfalls
       antwort["text"]= "falsch,", erg # im antwort label erscheint "falsch" und richtiges ergebnis
       #falsch = falsch + 1 # es wird eine 1 zu fasch addiert
       #eingabe_zeile.delete(0, END)#dann wird die eingabe des users gelöscht
    #statistik["text"]= "Richtig=" ,str(richtig), "Falsch=",str(falsch) # dann wird die statistik aktualiesiert


##def reset(): # der reset button soll den zähler bei beiden zahlen auf o stellen
##    global falsch, richtig # falsch und richtig werden in dieser definition verwendet
##    richtig = 0 # richtig wird auf 0 zurückgestellt
##    falsch = 0 # falsch wird auf 0 zurückgesttellt
##    statistik["text"]= "Richtig=" ,str (richtig), "Falsch=",str(falsch)# die statistik wird aktualisiert


#  ->>----THE-ABACUS-APPLICATION----<<- 
root = Tk() 
root.title("Abakus-Prototyp-27.01.04 - 03:00") 
root['bg'] = 'steelblue3' 
cv = Canvas(root,height=430,width=550,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', 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 Fenster, dass die dargestellte Zahl anzeigt
#sum = cv.create_text(60,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)) 

# rechnung button -> stellt neue Aufgabe zusammen
rechnung_button = Button(root,text="Neue Aufgabe",width=12,command=rechnung)
rechnung_button.pack(side="left")

# ausgabe label
ausgabe = Label(root,width=12,text="////////////")
ausgabe.pack(side="left")

# pruef button -> wertet ergebnis aus
pruef_button = Button(root,text="Nachprüfen", command = vergleich,width = 12)
pruef_button.pack(side="left")

# antwort label -> zeigt richtig oder falsch an
antwort= Label(root,width=12,text="richtig / falsch")
antwort.pack(side="left")

quit = Button(root, text="Beenden", width=10, command=root.destroy) 
quit.pack(side="right",pady=4) 

if not usingIDLE: 
    root.mainloop()
Es gibt diejenigen, die angeln, und diejenigen, die nur das Wasser trüben.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Niko

Ich habe noch etwas mit deinem erweiterten
Skript ausprobiert.
Meine Merker im Skript sind mit #-> wuf: xxxxxx
markiert.

Ich nehme an, dass du mit der Variable "zusammen"
die Summe aller nach rechts verschobener Perlen meinst?

Du kannst es einmal anschauen.

Code: Alles auswählen

from Tkinter import *
import random

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
	global sum            #-> wuf: Hinzugefügt
#	zusammen = ''
	zusammen = 0          #-> wuf: Modifiziert
	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)
		zusammen += numpearls      #-> wuf: Modifiziert
		print zusammen
	try:   #-> wuf: try & except freigegeben
	   cv.delete(sum)
	except:
	   pass
	sum = cv.create_text(60,420,text = zusammen, font = font1)  #-> wuf: freigegeben
#	print "zusammen = ",zusammen
	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()

def rechnung():
	global falsch, richtig # falsch und richtig werden in dieser definition verwendet
	z1 = random.randint(1.0,50.0)
	z2 = random.randint(1.0,50.0)
	op = random.randint(0,2) # die für die rechenoperation 3 zahlen weredn per zufall ausgesucht
	oplist = ['+', '-', '*'] # liste, aus der das rechenzeichen gewählt wird; bei 0 is das rechenzeicen + usw.
	global erg # das ergebnis wird global gemacht d.h ist für das ganze programm benutzbar
	if op == 0: erg = z1 + z2 # berechnet erg
	if op == 1: erg = z1 - z2 # berechnet erg
	if op == 2: erg = z1 * z2 # berechnet erg
	#if op == 3: erg = z1 / z2 # berechnet erg
	ausgabe["text"] = (z1, oplist[op] , z2)# das rechenzeichen aus der liste verbindet bei der ausgabe die beiden zahlen
	antwort["text"] = "" # das antwort label (das richtig oder falsch anzeigt) wird geleert
	#reset() ### WICHTIG:HIER SOLLTE ALLES VON ANFANG AN STARTEN!!!WIRKLICHES RESET,NICHT STATISTIK

def vergleich():
	global falsch, richtig # falsch und richtig werden in dieser definition verwendet
	eing = zusammen # die eingabe vom benutzer wird einer variablen zugeordnet
	if int(zusammen) == erg : # wenn die eingabe gleich dem ergebniss ist
		antwort["text"]= "richtig" # dann wird im antwort label "richtig" ausgegeben
		#richtig = richtig + 1 # in dem zähler wird zu richtig eine 1 addiert
		#eingabe_zeile.delete(0, END) # dann wird die eingabe des users gelöscht
	else: # andernfalls
		antwort["text"]= "falsch,", erg # im antwort label erscheint "falsch" und richtiges ergebnis
		#falsch = falsch + 1 # es wird eine 1 zu fasch addiert
		#eingabe_zeile.delete(0, END)#dann wird die eingabe des users gelöscht
	#statistik["text"]= "Richtig=" ,str(richtig), "Falsch=",str(falsch) # dann wird die statistik aktualiesiert


##def reset(): # der reset button soll den zähler bei beiden zahlen auf o stellen
##    global falsch, richtig # falsch und richtig werden in dieser definition verwendet
##    richtig = 0 # richtig wird auf 0 zurückgestellt
##    falsch = 0 # falsch wird auf 0 zurückgesttellt
##    statistik["text"]= "Richtig=" ,str (richtig), "Falsch=",str(falsch)# die statistik wird aktualisiert


#  ->>----THE-ABACUS-APPLICATION----<<-
root = Tk()
root.title("Abakus-Prototyp-27.01.04 - 03:00")
root['bg'] = 'steelblue3'
cv = Canvas(root,height=500,width=550,bd=4,relief=RAISED,bg='khaki2')  #-> wuf: height auf 500
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 = 10    # Anzahl der Perlenreihen            #-> wuf: auf 10 erhöht

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(60,420,text = text)        #-> wuf: freigegeben

#~~ 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))

# rechnung button -> stellt neue Aufgabe zusammen
rechnung_button = Button(root,text="Neue Aufgabe",width=12,command=rechnung)
rechnung_button.pack(side="left")

# ausgabe label
ausgabe = Label(root,width=12,text="////////////")
ausgabe.pack(side="left")

# pruef button -> wertet ergebnis aus
pruef_button = Button(root,text="Nachprüfen", command = vergleich,width = 12)
pruef_button.pack(side="left")

# antwort label -> zeigt richtig oder falsch an
antwort= Label(root,width=12,text="richtig / falsch")
antwort.pack(side="left")

quit = Button(root, text="Beenden", width=10, command=root.destroy)
quit.pack(side="right",pady=4)

if not usingIDLE:
    root.mainloop()
Gruss wuf :wink:
Take it easy Mates!
niko
User
Beiträge: 24
Registriert: Freitag 23. Januar 2004, 20:53

hi wuf!
also ich hab noch was gemacht. wie in der realität stehen nun auch im programm alle perlen rechts und die nach links verschobenen zählen.
und noch lauter kleinigkeiten.
hier der code:

Code: Alles auswählen

from Tkinter import * 
import random

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="green") 

   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="darkolivegreen3") 

   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 = left-28
      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(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()

def rechnung():
    global falsch, richtig # falsch und richtig werden in dieser definition verwendet
    z1 = random.randint(1.0,5.0)
    z2 = random.randint(1.0,5.0)
    op = random.randint(0,2) # bei 0 is das rechenzeicen + usw.
    oplist = ['+', '-', '*'] # liste, aus der das rechenzeichen gewählt wird 
    global erg
    if op == 0: erg = z1 + z2 # berechnet erg
    if op == 1: erg = z1 - z2 # berechnnet erg         
    if op == 2: erg = z1 * z2 # berechnet erg
    #if op == 3: erg = z1 / z2 # berechnet erg
    if erg == 0:               # wenn das ergebnis gleich 0 ist, dann wird...
       z1 = z1+1               # ...zu z1 1 hinzu addiert...
       erg = z1 - z2           # ...und das ergebnis aktualisiert
    if erg < 0:                # wenn das ergebnis negativ ist, dann werden die 2 gezogenen Zahlen vertauscht->erg positiv 
       ausgabe["text"] = (z2, oplist[op], z1)  # das rechenzeichen aus der liste verbindet bei der ausgabe die beiden zahlen
    else:
       ausgabe["text"] = (z1, oplist[op], z2)  # das rechenzeichen aus der liste verbindet bei der ausgabe die beiden zahlen
    antwort["text"] = "" # das antwort label (das richtig oder falsch anzeigt) wird geleert
    
    
def vergleich():
    #global falsch, richtig # falsch und richtig werden in dieser definition verwendet
    eing = zusammen # die eingabe vom benutzer wird einer variablen zugeordnet
    if int(zusammen) == erg :     # wenn Benutzereingabe mit ergebnis übereinstimmt...
       antwort["text"]= "richtig" # ...dann wird im antwort label "richtig" ausgegeben
    else:                              # ansonsten 
       antwort["text"]= "falsch,", erg # erscheint im antwort label "falsch" und das richtige ergebnis
       
def reset():
   try:
      MoveRight(ALL)
   except:
      pass
   ausgabe['text']=''
   antwort['text']=''
   
#  [--DER--ABAKUS--] 
root = Tk() 
root.title("Abakus") 
root['bg'] = 'steelblue3' 
cv = Canvas(root,height=430,width=550,bd=4,relief=RAISED,bg='steelblue3')#'khaki2') 
cv.pack() 

usingIDLE = 1 

#~~ 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
more    = 10    # nochmalige Einrückung des Abakus
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+more# 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+1+(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    = left-28 
  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(60,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 = 2*s+more+2+x*r 
     y0 = s+yg+y*r 
     x1 = 2*s+more+2+(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)) 

# rechnung button -> stellt neue Aufgabe zusammen
rechnung_button = Button(root,text="Neue Aufgabe",width=12,command=rechnung)
rechnung_button.pack(side="left")

# ausgabe label
ausgabe = Label(root,width=12,text="////////////")
ausgabe.pack(side="left")

# pruef button -> wertet ergebnis aus
pruef_button = Button(root,text="Nachprüfen",width = 12,command=vergleich)
pruef_button.pack(side="left")

# antwort label -> zeigt richtig oder falsch an
antwort= Label(root,width=12,text="richtig / falsch")
antwort.pack(side="left")

# reset button -> setzt alles auf null
reset = Button(root,text="Reset",width=12,command=reset)
reset.pack(side="left")

quit = Button(root, text="Beenden", width=10, command=root.destroy) 
quit.pack(side="right") 

if not usingIDLE: 
    root.mainloop()
Mfg
Niko
Es gibt diejenigen, die angeln, und diejenigen, die nur das Wasser trüben.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Niko

Ich sehe dein Skript wächts und wächst.
Wünsche dir viel spass und Erfolg! Um es
laufen zu lassen muss die Flag "usingIDLE"
noch auf Null gesetzt werden.

Gruss wuf :wink:
Take it easy Mates!
Antworten