polygon im canvas bewegen

Fragen zu Tkinter.
Antworten
geogre
User
Beiträge: 41
Registriert: Mittwoch 20. April 2005, 13:26

hallo!

weiss jemand wie ich ein polygon (z.b. so ein eckiges ding wie das hier) z.b. mehrmals an verschiedenen stellen in einem canvas platziere? oder wie ich anders an das problem herangehe? ich möchte für eine art brettspiel 'zeichen' erstellen (nur einmal) und die dann an verschiedenen stellen auf dem spielbrett platzieren (und höchstwahrscheinlich auch skalieren), das sollte ja aber wenn ich das erste geklärt habe mit scale kein problem sein.

das problem ist, das meine punktefolge teilweise sehr lang ist und ich das gefühl habe, dass ich für den coords-befehl alle neuen koordinaten für alle punkte (das können z.b. 100 sein) angeben muss, das will ich aber nicht, ich möchte nur x,y und skalierfaktor angeben (am liebsten).

und ich möchte gerne bei tkinter bleiben, da ich noch anfänger bin und da schon einiges verstehe und mich vielleicht einfach erst später an andere guis ranwagen will.

danke für tipps!!

Code: Alles auswählen

dings=canvas.create_polygon(114.6854,177.1773,\
                       231.6983,50.3356,\
                       344.8477,246.6644,\
                       75.4970,84.5277,\
                       297.3801,197.5822,\
                       228.9386,87.2851)
geogre
User
Beiträge: 41
Registriert: Mittwoch 20. April 2005, 13:26

... oder wie ich z.b. obiges erstellte einfach z.b. um 20 pixel nach rechts verschiebe?
BlackJack

Dazu gibt's die `move()` Methode auf `Canvas` Objekten:

Code: Alles auswählen

import random
import Tkinter as Tk

def make_move(canvas, item):
    def move():
        canvas.move(item, random.randint(-10, 10), random.randint(-10, 10))
    return move


root = Tk.Tk()
canvas = Tk.Canvas(root, width=400, height=400, bg='white')
canvas.pack()
polygon_id = canvas.create_polygon(10, 10, 20, 30, 0, 30, fill='green')
canvas.move(polygon_id, 200, 200)

button = Tk.Button(root, text='Move', command=make_move(canvas, polygon_id))
button.pack()

root.mainloop()
geogre
User
Beiträge: 41
Registriert: Mittwoch 20. April 2005, 13:26

oh mann... danke. ich muss echt blind gewesen sein MOVE zu übersehen, steht auch in meinem buch im canvas-kapitel... *an die stirn klatsch* - danke!!!


ich probiere jetzt gerade ein 'symbol' häufiger zu erzeugen, ich habe in einer liste alle punkte des symbols (polygons) wiederum als liste oder tupel gespeichert (mit 2 elementen, klar).

jetzt erzeuge ich z.b. 25 dieser symbole so:

Code: Alles auswählen

shapecoords=[[0,0],[10,10],[-10,10]]

symbole=[]
for i in range(25):
    x=i%5
    y=int(i/5)
    symbole.append(kannwas.create_polygon([[i[0]+x*10,i[1]+y*10] for i in shapecoords]))
das geht auch. aber ich möchte jetzt wenn mein canvas mit configure resized wird in der resize funktion den inhalt an die neue größe anpassen. daher muss ich wohl alle elemente in 'symbole' mit neuen coords versorgen.
und das geht nicht!!! so versuche ich es:

Code: Alles auswählen

a=0
for i in symbole:
        x=a%5
        y=int(a/5)
        kannwas.coords(i,[[s[0]+x*zelle,s[1]+y*zelle] for s in shapecoords])
        a=a+1
zelle ist ein wert, der vorher aus der neuen canvas-größe ermittelt wurde.
ich bekomme immer folgende fehlermeldung:

bad screen distance "10.0]]"

als würde ich irgendwie einen string als koordinaten übergeben der noch die ]] enthält, ich hab echt schon viel rumprobiert, tupel verwendet, int verwendet weil ich dachte es geht nur mit ganzzahlenkoordinaten usw, aber immer das gleiche. kann mir jemand einen tipp geben bitte ???[/code]
geogre
User
Beiträge: 41
Registriert: Mittwoch 20. April 2005, 13:26

also, mit anderen worten kann ich offenbar bei crete_polygon eine liste mit koordinaten (und das auch noch verschachtelt, also [[x0,y0],[x1,y1]] usw) nehmen, beim coords-befehl aber nicht! und auch kein tupel. da ich aber für viele polygone neue koordinaten berechnen muss... wie mache ich das? die anzahl der punkte ist ja nicht bei allen symbolen gleich und teils sehr gross und teils sehr klein. ich hab grad ein brett vorm kopf *klonk*
BlackJack

Die Koordinaten beim Aufruf mit ``*`` "entpacken": canvas.coords(item, *shapecoords)
geogre
User
Beiträge: 41
Registriert: Mittwoch 20. April 2005, 13:26

genial!!!!! tausend dank blackjack!!!!
da wäre ich NIE von alleine drauf gekommen, nicht sehr python-mäßig finde ich. wo kann ich mehr darüber lesen, was dieses 'entpacken' macht und warum man es anwenden muss?
scheinbar kann ich es nicht in kombination mit for anwenden, also so ähnlich

canvas.coords(shape,*[[x[0]+a,x[1]+a] for x in shapecoords])

?? hat bei mir jedenfalls nicht geklappt. ich habe vorher in einer forschleife eine nichtverschachtelte liste mit denn coords erzeugt und es klappt wunderbar mit deinem sternchen...
nochmals danke!!
BlackJack

geogre hat geschrieben:genial!!!!! tausend dank blackjack!!!!
da wäre ich NIE von alleine drauf gekommen, nicht sehr python-mäßig finde ich. wo kann ich mehr darüber lesen, was dieses 'entpacken' macht und warum man es anwenden muss?
Dieses 'entpacken' nimmt den Inhalt des "iterable" und fügt ihn an der Stelle in die Argumentliste ein:

Code: Alles auswählen

a = [1, 2, 3]
foo(0, *a) # -> foo(0, 1, 2, 3)
scheinbar kann ich es nicht in kombination mit for anwenden, also so ähnlich

canvas.coords(shape,*[[x[0]+a,x[1]+a] for x in shapecoords])

?? hat bei mir jedenfalls nicht geklappt.
Nö, die Liste hat ja auch nicht die Form in der `coords()` seine Parameter haben möchte. Das möchte die Koordinaten-Komponenten alle einzeln und nicht je eine x- und y-Koordinate in einer Liste.
geogre
User
Beiträge: 41
Registriert: Mittwoch 20. April 2005, 13:26

danke für die infos!

das mit dem format für den coords-befehl ist ja eigentlich klar (ich frage mich, warum man [ich] manchmal sachen die so klar sind erst hinterher sieht ;). und wenn ich noch ein * verwenden würde? etwa so

canvas.coords(shape,*[*[x[0]+a,x[1]+a] for x in shapecoords])

ich hab's natürlich schon ausprobiert und es ging nicht ;) und das hier

a=[1,2,3]
b=[0,*a]

geht auch nicht.
kann man das * also nur in funktions-aufrufen verwenden ? (nur so interessehalber, mein problem betrachte ich als geklärt und bin superglücklich über mein skalierbares spielbrett!! - danke nochmal)
Antworten