0

I'm having a problem that when i try to create an image on the canvas i am unable to produce the image. However before my after() loop is initiated i am able to create and configure my images. Also, i am able to remove objects from my canvas using canvas.delete() in my after() loop so i do still have some level of control.

I am on windows 8.1, using Python 3.5.4

import tkinter as tk
from PIL import Image, ImageTk
from math import floor
import numpy as np
from scipy import ndimage

root = tk.Tk()
HEIGHT = 600
WIDTH = 600
CANVAS_MID_X = WIDTH / 2
CANVAS_MID_Y = HEIGHT / 2

def my_mainloop():
    #THIS WORKS!!! REMOVES THE DIAL CREATED BEFORE THE MAINLOOP
    canvas.delete(dial_1)

    #THIS WORKS BELOW BEFORE MAINLOOP, BUT NOT IT WONT WORK! (use opencv?)
    img = dial_1_img_resized
    img2 = img.rotate(45, expand=True)
    dial_1_photo_new = ImageTk.PhotoImage(img2)
    dial_2 = canvas.create_image((dial_1_center), image=dial_1_photo_new, anchor=tk.E)
    '''CANT DRAW TO CANVAS IN AFTER LOOP'''
    print("loop!")
    root.after(4000,my_mainloop)

'''-------------------Create Canvas, and starting dials in their starting positions---------------------'''

canvas = tk.Canvas(root, width=HEIGHT, height=WIDTH, bg="black")
canvas.grid(row=0, column=0)
dial_1_path = "gauge1.png"
dial_1_width = 400

dial_1_img = Image.open(dial_1_path, 'r') #open image
dial_1_img_ratio = int(dial_1_img.size[1]) / int(dial_1_img.size[0])
dial_1_img_resized = dial_1_img.resize((dial_1_width, floor(dial_1_img_ratio * dial_1_width)), 1)
dial_1_photo = ImageTk.PhotoImage(dial_1_img_resized)
dial_1_center = (CANVAS_MID_X, CANVAS_MID_Y)

#CREATE DIAL ON CANVAS, THIS WORKS!!
dial_1 = canvas.create_image((dial_1_center), image=dial_1_photo)



'''Start Main Loop'''
root.after(0, my_mainloop)
root.mainloop()

Therefore my question is: is there a way to manipulate and create canvas images in the after() loop? (called my_mainloop) any help is appreciated!

DiscreteTomatoes
  • 769
  • 1
  • 14
  • 30
  • 1
    It is not clear what you expect to happen that is not happening. Try to reduce the code to the bare essentials. See https://stackoverflow.com/help/mcve – Terry Jan Reedy Mar 22 '18 at 01:19
  • 1
    Your image might be getting garbage collected. This post might be useful https://stackoverflow.com/questions/16424091/why-does-tkinter-image-not-show-up-if-created-in-a-function – busybear Mar 22 '18 at 01:20
  • i tried to simplify my code, and thanks busybear i will read into it – DiscreteTomatoes Mar 22 '18 at 01:25

1 Answers1

2

You'll need to save a reference to your photo because it is being garbage collected after my_mainloop runs. You can add it to your canvas object for instance:

canvas.dial_1_photo_new = ImageTk.PhotoImage(img2)
dial_2 = canvas.create_image((dial_1_center), image=canvas.dial_1_photo_new, anchor=tk.E)
busybear
  • 10,194
  • 1
  • 25
  • 42