Kein Attribut 'create_oval' im Objekt '_tkinter.tkapp'

Fragen zu Tkinter.
Antworten
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

Hallo

Ich beschäftige mich gerade mit Tkinter in Python 3.

Aktuell würde ich gerne weiße Punkte auf einen schwarzen Bildschirm im Vollbildmodus zeichnen und deren Position mithilfe einer Schleife dauernd abändern.

Mein Code sieht wie folgt aus:

Code: Alles auswählen

from tkinter import *

def paint(x, y):
    x1, y1 = (x - 5), (y - 5)
    x2, y2 = (x + 5), (y + 5)
    root.create_oval(x1, y1, x2, y2, fill="#ffffff")


if __name__ == "__main__":
    root = Tk()
    root.attributes('-fullscreen', True)
    root.geometry("%dx%d+0+0" % (root.winfo_screenwidth(), root.winfo_screenheight()))
    root.focus_set()
    root.configure(background='black')
    root.bind("<Escape>", lambda e: root.quit())

    paint(500,500) #Test

    root.mainloop()

Leider kommt es beim Aufruf der Funktion paint() zu folgendem Fehler:

Code: Alles auswählen

Traceback (most recent call last):
  File "/home/ata/source/Test/main.py", line 19, in <module>
    paint(500,500) #Test
  File "/home/ata/source/Test/main.py", line 8, in paint
    root.create_oval(x1, y1, x2, y2, fill="#ffffff")
  File "/usr/lib/python3.6/tkinter/__init__.py", line 2098, in __getattr__
    return getattr(self.tk, attr)
AttributeError: '_tkinter.tkapp' object has no attribute 'create_oval'
Was mache ich falsch?

Gruß
Atalanttore
Benutzeravatar
__blackjack__
User
Beiträge: 13006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Du rufst eine Methode von `Canvas`-Objekten auf einem `Tk`-Objekt auf.

Ansonsten `root` sollte nicht auf Modulebene bestehen sondern in einer Funktion. Also der ganze Code in dem ``if``-Zweig. Was dann auch dazu führt, das man der `paint()`-Funktion nicht nur die Koordinaten übergeben muss, sondern auch das Objekt auf dem `create_oval()` aufgerufen wird.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

Okay, dann kann es ja nicht funktionieren.

Ich habe den Code mal angepasst, damit das Programm läuft, und zum Test eine Schleife zum Anordnen der Punkte in einem Kreis eingebaut.

Code: Alles auswählen

from tkinter import *
from math import cos, sin


def point_on_circle(radius, angle, center_x, center_y):
    x = center_x + (radius * cos(angle))
    y = center_y + (radius * sin(angle))
    return x, y


def paint(x, y, window):
    x1, y1 = (x - 8), (y - 8)
    x2, y2 = (x + 8), (y + 8)
    window.create_oval(x1, y1, x2, y2, fill="#ffffff")


def main():
    root = Tk()
    root.attributes("-fullscreen", True)
    root.focus_set()
    root.bind("<Escape>", lambda e: root.quit())

    width = root.winfo_screenwidth()
    height = root.winfo_screenheight()
    center_x = width / 2
    center_y = height / 2

    window = Canvas(root, width=width, height=height, bg="black")
    window.pack()

    for i in range(0, 360, 15):
        x, y = point_on_circle(300, i, center_x, center_y)
        print(x, y)
        paint(x, y, window)

    root.mainloop()


if __name__ == "__main__":
    main()
Komischerweise fehlen ein paar Punkte auf dem Kreis und die Abstände zwischen den Punkten sind auch nicht so akkurat wie erwartet.
Bild

Gruß
Atalanttore
Benutzeravatar
__blackjack__
User
Beiträge: 13006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Atalanttore: Das ist nur komisch solange man davon ausgeht das `cos()` und `sin()` Grad als Einheit erwarten, was sie nicht tun. Das `math`-Modul bietet aber eine Funktion zum Umrechnen. :-)
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

Wie folgt angepasst funktioniert es.

Code: Alles auswählen

    x = center_x + (radius * math.cos(math.radians(angle)))
    y = center_y + (radius * math.sin(math.radians(angle)))
Wie konnte ich nur davon ausgehen, dass `cos()` und `sin()` Grad und nicht Radiant als Einheit erwarten ... :oops:

Gruß
Atalanttore
Antworten