Bartłomiej 'furas' Burek
furas.pl
# prywatne notatki - Python, Linux, Machine Learning, etc.

Tkinter: Zmiana obrazka na Canvas po wciśnięciu Button'a

Przykładowe obrazki

python python python

Zmiana tylko raz

Utwórz dwa ImagePhoto

image1 = tk.PhotoImage(file="ball1.gif")
image2 = tk.PhotoImage(file="ball2.gif")

Umieść pierszy obrazek na Canvas i zachowaj jego ID (image_id).

image_id = canvas.create_image(0, 0, anchor='nw', image=image1)

(Normalnie by ustawiło środek obrazka w punkcie (0,0) ale używając anchor='nw' ustawi górny-lewy róg obrazka w punkcie (0,0). nw oznacza narożnik nord west/górny lewy.)

Kiedy klikniesz na przycisk to zmień obazek na nowy

canvas.itemconfig(image_id, image=image2)

Pełny kod

import tkinter as tk

# --- functions ---

def on_click():
    # change image on canvas
    canvas.itemconfig(image_id, image=image2)

# --- main ---

root = tk.Tk()

# canvas for image
canvas = tk.Canvas(root, width=60, height=60)
canvas.pack()

# button to change image
button = tk.Button(root, text="Change", command=on_click)
button.pack()

# images
image1 = tk.PhotoImage(file="ball1.gif")
image2 = tk.PhotoImage(file="ball2.gif")

# set first image on canvas
image_id = canvas.create_image(0, 0, anchor='nw', image=image1)

root.mainloop()

Zmiana wiele razy - i powrót do pierszego obrazka

Aby zmieniac obrazki wiele razy i powrócić do pierwszego obrazka dobrze jest trzymać obrazki na liście

images = [
    tk.PhotoImage(file="ball1.gif"),
    tk.PhotoImage(file="ball2.gif"),
    tk.PhotoImage(file="ball3.gif"),
]

i użyć zmiennej, która wskazuje, który obrazek ma być wyświetlony

current_image_number = 0

Używając tej zmienne można ustawić pierwszy obrazek

image_id = canvas.create_image(0, 0, anchor='nw', image=images[current_image_number])

a kiedy przycisk zostanie wciśnięty wtedy należy zwiększyć zmienną, sprawdzić czy nie przekroczyła wielkości listy, i użyć jej do zamiany obrazka

current_image_number += 1

if current_image_number == len(images):
    current_image_number = 0

canvas.itemconfig(image_id, image=images[current_image_number])

W funkcji trzeba użyć global aby zmienić zewnętrzą zmienną

Pełny kod

import tkinter as tk

# --- functions ---

def on_click():
    global current_image_number

    # next image
    current_image_number += 1

    # return to first image
    if current_image_number == len(images):
        current_image_number = 0

    # the same using modulo `%` 
    #current_image_number = (current_image_number+1) % len(images)

    # change image on canvas
    canvas.itemconfig(image_id, image=images[current_image_number])

# --- main ---

root = tk.Tk()

# canvas for image
canvas = tk.Canvas(root, width=60, height=60)
canvas.pack()

# button to change image
button = tk.Button(root, text="Change", command=on_click)
button.pack()

# images
images = [
    tk.PhotoImage(file="ball1.gif"),
    tk.PhotoImage(file="ball2.gif"),
    tk.PhotoImage(file="ball3.gif"),
]
current_image_number = 0

# set first image on canvas
image_id = canvas.create_image(0, 0, anchor='nw', image=images[current_image_number])

root.mainloop()

Użycie klasy

Można zrobić to samo z użyciem klasy i wtedy zamiast global można użyć self.

import tkinter as tk

# --- classes ---

class MainWindow():

    def __init__(self):
        self.master = tk.Tk()

        # canvas for image
        self.canvas = tk.Canvas(self.master, width=60, height=60)
        self.canvas.pack()

        # images
        self.images = [
            tk.PhotoImage(file="ball1.gif"),
            tk.PhotoImage(file="ball2.gif"),
            tk.PhotoImage(file="ball3.gif"),
        ]
        self.current_image_number = 0

        # set first image on canvas
        self.image_on_canvas = self.canvas.create_image(0, 0, anchor='nw', image=self.images[self.current_image_number])

        # button to change image
        self.button = tk.Button(self.master, text="Change", command=self.on_click)
        self.button.pack()

        self.master.mainloop()

    def on_click(self):

        # next image
        self.current_image_number += 1

        # return to first image
        if self.current_image_number == len(self.images):
            self.current_image_number = 0

        # change image on canvas
        self.canvas.itemconfig(self.image_on_canvas, image=self.images[self.current_image_number])

# --- main ---

MainWindow()
Książki: python-dla-kazdego-podstawy-programowania python-wprowadzenie python-leksykon-kieszonkowy python-receptury python-programuj-szybko-i-wydajnie python-projekty-do-wykorzystania black-hat-python-jezyk-python-dla-hackerow-i-pentesterow efektywny-python-59-sposobow-na-lepszy-kod tdd-w-praktyce-niezawodny-kod-w-jezyku-python aplikacje-internetowe-z-django-najlepsze-receptury