Canvas bewegt falsches Objekt

Fragen zu Tkinter.
Antworten
3komma141592
User
Beiträge: 4
Registriert: Sonntag 27. Mai 2018, 14:25

Hallo,
ich habe ein Skript geschrieben, das oben links einen großen blauen Kreis und unten rechts viele kleine graue Kreise erstellt. Anschließend sollen sich die grauen Kreise zufällig bewegen.

Code: Alles auswählen

from tkinter import *
from time import sleep
from random import randint

top = Tk()
C = Canvas(top, height = 700, width = 1300)
C.pack()

goal = C.create_oval(1,1,100,100,fill="blue")
number = 1
for _ in range(100):
    number = C.create_oval(1200,600,1210,610,fill="gray")
    number = number + 1

number = 1
for _ in range(100):
    for _ in range(100):
        C.move(number,randint(-10,10),randint(-10,10))
        number = number + 1
    C.update()
    number = 1

top.mainloop()
So weit, so gut. Jetzt wird aber auch der blaue Kreis("goal") bewegt, obwohl ich nur die nach Nummern benannten grauen Kreise aufrufe.
Warum ist das so?
Wie kann ich das verhindern?

Grüße,
Pi :mrgreen:
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

Das was Du da mit `number` beim Erzeugen machst, ist Unsinn. Die Id's die Du von create_oval bekommst, nutzt Du gar nicht, und dass sich überhaupt irgendetwas beweget, kommt nur davon, dass die Id's von 1 ab durchnummeriert werden.

Du mußt Dir die Id jedes Kreises in einer Liste merken:

Code: Alles auswählen

import tkinter as tk
from time import sleep
from random import randint

top = tk.Tk()
canvas = tk.Canvas(top, height=700, width=1300)
canvas.pack()

goal = canvas.create_oval(1, 1, 100, 100, fill="blue")
circles = []
for _ in range(100):
    circles.append(canvas.create_oval(1200, 600, 1210, 610, fill="gray"))

for _ in range(100):
    for circle in circles:
        canvas.move(circle, randint(-10,10), randint(-10,10))
    canvas.update()

top.mainloop()
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst dir die Nummern die du bekommst merken. Statt zu versuchen da selbst irgendwie mit rum zu hantieren. Es gibt keine Garantie, dass die aufsteigend und bei 1 anfangen.

Also einfach eine Liste erzeugen, jede graue Element-ID darin merken, und dann mit einem simplen

Code: Alles auswählen

for item in gray_items: 
      ....
darüber iterieren und sie bewegen.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi 3komma141592

Funktioniert es so besser?:

Code: Alles auswählen

from tkinter import *
from time import sleep
from random import randint

top = Tk()
canvas = Canvas(top, height = 700, width = 1300)
canvas.pack()

goal = canvas.create_oval(1,1,100,100,fill="blue")
print("Goal:", goal)

for _ in range(100):
    number = canvas.create_oval(1200,600,1210,610,fill="gray")
    print("Number:", number)
    
number = 2
for _ in range(100):
    for _ in range(100):
        canvas.move(number,randint(-10,10),randint(-10,10))
        number = number + 1
    canvas.update()
    number = 2

top.mainloop()
Canvas Objekte werden auf diese Art nummeriert angelegt. Dein Canvas-Objekt goal hat die Nummer 1 und das erste Canvas-Objekt number die Nummer 2 usw. Also die Bewegung der Canvas-Objekte number begingt mit der Nummer 2.

Gruss wuf ;-)
Take it easy Mates!
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@wuf: nein, so ist es nicht besser. Besser ist es, wie ich es gezeigt habe.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Sirius3 hat geschrieben:@wuf: nein, so ist es nicht besser. Besser ist es, wie ich es gezeigt habe.
Würde ich so nicht behaupten. Es ist einfach eine bereinigte Variante.

Gruss wuf ;-)
Take it easy Mates!
3komma141592
User
Beiträge: 4
Registriert: Sonntag 27. Mai 2018, 14:25

Okay, vielen Dank für die schnellen Antworten! :D
@Sirius3 Deine Lösung ist wohl die elegantere, während die von @wuf den "Fehler" ausnutzt. Ich werde wahrscheinlich die von Sirius nutzen, einfach weil sie kürzer ist. Schönen Abend euch noch! 8)
Antworten