Rysowanie po canvasie podczas głównej pętli programu.

0

Cześć.

Kolejny raz podchodzę do pythona co jest nieco ciężkie dla mnie. W jaki sposób mogę sobie rysować po canvasie w tle? W C++, modyfikował bym obiekt canvasu po czym wyzwalał funkjcę updatu takiego obiektu. W przypadku pythona za bardzo nie wiem jak to zrobić. Mogę po canvasie wyrysować coś, ale żeby to się pokazało muszę wywołać mainloop, inaczej nie widzę okienka. Wpadając w główną pętlę nie potrafię już dorysować tam nic. W jaki sposób mogę gdzieś asynchronciznie, w innym wątku modyfikować obiekt canvy i coś rysować? Robię to pierwszy raz w pythoni i wyklepałem taki example :

import tkinter
from tkinter import constants
from tkinter import ttk
from tkinter import Tk, Canvas
import time

print(tkinter.TkVersion)

root = Tk()
root.geometry("500x500")

canv = Canvas(root, width=500, height=500)
canv.pack()

canv.create_rectangle(100, 50, 120, 55, fill='green')


root.mainloop()
0

Musisz wcześniej zdefiniować, jak Twój obiekt ma być malowany. Przyznam szczerze, że nie pracuję z Tkinterem na co dzień, więc wspomogłem się tym postem. Stworzyłem coś na kształt kontrolowanego błądzenia losowego prostokąta. Jest kontrolowany, ponieważ porusza się po przekątnej z małymi odstępstwami. Tutaj kod:

#!/usr/bin/env python3

import tkinter as tk
import time
from random import randint


class Rectangle(object):

    def __init__(self, canvas, *args, **kwargs):
        self.canvas = canvas
        self.id = canvas.create_rectangle(*args, **kwargs)


class App(object):

    def __init__(self, master, **kwargs):
        self.master = master
        self.canvas = tk.Canvas(self.master, width=1000, height=500)
        self.canvas.pack()
        self.dx = 40
        self.dy = 20
        self.rectangles = [
            Rectangle(self.canvas, 0, 0, self.dx, self.dy, fill='green')
        ]
        self.canvas.pack()
        self.rec_num = 0
        self.master.after(0, self.add)

    def add(self):
        self.rec_num = len(self.rectangles)
        new_rectangle = None
        self.random_step = 30

        if self.rec_num < 50:
            x0, y0 = (randint(-self.random_step, self.random_step),
                      randint(-self.random_step, self.random_step))
            new_rectangle = Rectangle(
                self.canvas,
                self.rec_num*self.dx + x0, self.rec_num*self.dy + y0,
                (self.rec_num + 1)*self.dx + x0,
                (self.rec_num + 1)*self.dy + y0,
                fill='green')

        self.rectangles.append(new_rectangle)
        self.master.after(400, self.add)


root = tk.Tk()
app = App(root)
root.mainloop()

1 użytkowników online, w tym zalogowanych: 0, gości: 1