Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #77319 > unrolled thread

Sequencing images using tkinter?

Started bytheteacher.info@gmail.com
First post2014-08-30 08:54 -0700
Last post2014-08-31 02:51 -0700
Articles 9 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  Sequencing images using tkinter? theteacher.info@gmail.com - 2014-08-30 08:54 -0700
    Re: Sequencing images using tkinter? Terry Reedy <tjreedy@udel.edu> - 2014-08-30 15:52 -0400
    Re: Sequencing images using tkinter? Peter Otten <__peter__@web.de> - 2014-08-30 21:54 +0200
    Re: Sequencing images using tkinter? theteacher.info@gmail.com - 2014-08-30 13:11 -0700
    Re: Sequencing images using tkinter? theteacher.info@gmail.com - 2014-08-30 13:27 -0700
      Re: Sequencing images using tkinter? "Albert Visser" <albert.visser@gmail.com> - 2014-08-30 22:49 +0200
    Re: Sequencing images using tkinter? theteacher.info@gmail.com - 2014-08-30 13:37 -0700
      Re: Sequencing images using tkinter? Peter Otten <__peter__@web.de> - 2014-08-30 23:14 +0200
        Re: Sequencing images using tkinter? theteacher.info@gmail.com - 2014-08-31 02:51 -0700

#77319 — Sequencing images using tkinter?

Fromtheteacher.info@gmail.com
Date2014-08-30 08:54 -0700
SubjectSequencing images using tkinter?
Message-ID<dcff98af-47cd-4dbc-9fa1-02dc6813df81@googlegroups.com>
I've started to learn to use tkinter but can't seem to rotate images.

Here is a Python 3.4 program to illustrate the problem. Anyone spot why the for loop doesn't seem to want to display a sucssession of images please? Thanks.

import sys
from tkinter import *
import random
from time import sleep

myGui = Tk()
myGui.geometry("1000x800+400+100")
myGui.title("The Random Machine")

monsters = ["py01.gif", "py02.gif", "py03.gif", "py04.gif", "py05.gif", "py06.gif", "py07.gif", "py08.gif",
            "py09.gif", "py10.gif", "py11.gif", "py12.gif", "py13.gif", "py14.gif", "py15.gif", "py16.gif",
            "py17.gif", "py18.gif", "py19.gif", "py20.gif",]


#Main canvas
canvas1 = Canvas(myGui, width=1000, height=800, bg="white")
canvas1.place(x=0,y=0)


#button
myButton1=Button(canvas1, text='OK', justify = LEFT)

for i in range(10):
   myImage = PhotoImage(file="MonsterImages/Converted/" + random.choice(monsters))
   myButton1.config(image=myImage, width="100", height="200")
   myButton1.place(x=500,y=300)
   sleep(0.2)

myGui.mainloop()

[toc] | [next] | [standalone]


#77327

FromTerry Reedy <tjreedy@udel.edu>
Date2014-08-30 15:52 -0400
Message-ID<mailman.13649.1409428360.18130.python-list@python.org>
In reply to#77319
On 8/30/2014 11:54 AM, theteacher.info@gmail.com wrote:
> I've started to learn to use tkinter but can't seem to rotate images.
>
> Here is a Python 3.4 program to illustrate the problem.
 > Anyone spot why the for loop doesn't seem to want to display
 > a sucssession of images please? Thanks.
>
> import sys
> from tkinter import *
> import random
> from time import sleep
>
> myGui = Tk()
> myGui.geometry("1000x800+400+100")
> myGui.title("The Random Machine")
>
> monsters = ["py01.gif", "py02.gif", "py03.gif", "py04.gif", "py05.gif", "py06.gif", "py07.gif", "py08.gif",
>              "py09.gif", "py10.gif", "py11.gif", "py12.gif", "py13.gif", "py14.gif", "py15.gif", "py16.gif",
>              "py17.gif", "py18.gif", "py19.gif", "py20.gif",]
>
>
> #Main canvas
> canvas1 = Canvas(myGui, width=1000, height=800, bg="white")
> canvas1.place(x=0,y=0)
>
>
> #button
> myButton1=Button(canvas1, text='OK', justify = LEFT)
>
> for i in range(10):
>     myImage = PhotoImage(file="MonsterImages/Converted/" + random.choice(monsters))
>     myButton1.config(image=myImage, width="100", height="200")
>     myButton1.place(x=500,y=300)
>     sleep(0.2)
>
> myGui.mainloop()

I tried a simplified version of this in the Idle shell. Idle displays 
call tips if you pause after typing '('.  Unlike .pack and .grid, .place 
apparently does not automatically put the widget in its master. At least 
this is true when placing in a canvas. You need an 'in_' argument (the 
'_' is needed to not be the keyword 'in').  Try

canvas1.pack() #don't use place unless really needed.
...
myButton1.place(in_=canvas1, x=500, y=300)

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#77328

FromPeter Otten <__peter__@web.de>
Date2014-08-30 21:54 +0200
Message-ID<mailman.13650.1409428506.18130.python-list@python.org>
In reply to#77319
theteacher.info@gmail.com wrote:

> I've started to learn to use tkinter but can't seem to rotate images.
> 
> Here is a Python 3.4 program to illustrate the problem. Anyone spot why
> the for loop doesn't seem to want to display a sucssession of images
> please? Thanks.

GUI programs are different from simple scripts; they have to react when the 
user resizes the window, clicks on a button, etc. The usual way to do that 
is to run an event loop permanently that calls functions that do something 
for a relatively small amount of time and then give control back to the 
loop.

time.sleep() in contrast stops the whole script (I'm simplifying) and thus 
should not be used here. Instead you can use myGui.after() to trigger the 
execution of a Python function:

> import sys
> from tkinter import *
> import random
> from time import sleep
> 
> myGui = Tk()
> myGui.geometry("1000x800+400+100")
> myGui.title("The Random Machine")
> 
> monsters = ["py01.gif", "py02.gif", "py03.gif", "py04.gif", "py05.gif",
> "py06.gif", "py07.gif", "py08.gif",
>             "py09.gif", "py10.gif", "py11.gif", "py12.gif", "py13.gif",
>             "py14.gif", "py15.gif", "py16.gif", "py17.gif", "py18.gif",
>             "py19.gif", "py20.gif",]
> 
> 
> #Main canvas
> canvas1 = Canvas(myGui, width=1000, height=800, bg="white")
> canvas1.place(x=0,y=0)

# prepare a list of `PhotoImage`s to avoid having to load an image
# more than once
monster_images = [
    PhotoImage(file="MonsterImages/Converted/" + monster)
    for monster in monsters]

#Main canvas
canvas1 = Canvas(myGui, width=1000, height=800, bg="white")
canvas1.place(x=0,y=0)

#button
myButton1 = Button(canvas1, text='OK', justify=LEFT)
myButton1.config(width="100", height="200")
myButton1.place(x=500, y=300)

def next_image():
    myButton1.config(image=random.choice(monster_images))

    # tell tkinter to invoke next_image() again after 200 miliseconds
    myGui.after(200, next_image)

# invoke next_image() for the first time
next_image()

myGui.mainloop()

[toc] | [prev] | [next] | [standalone]


#77329

Fromtheteacher.info@gmail.com
Date2014-08-30 13:11 -0700
Message-ID<215ce6a7-2b67-4386-ad09-0e448091d903@googlegroups.com>
In reply to#77319
Peter - Thanks! I've had a play around and followed your advice and have something that should take me on to the next step! This is what I have so far and it works, Thanks.

from tkinter import *
from tkinter import ttk
import random

root = Tk()
root.title("Messing about")

def next_image(): 
    myLabel.config(image=random.choice(monster_images)) 
    # tell tkinter to invoke next_image() again after 200 miliseconds 
    root.after(200, next_image) 

mainframe = ttk.Frame(root, padding="3 3 12 12", width="800", height="600", borderwidth="120", relief="sunken")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

mon1 = PhotoImage(file="MonsterImages/Converted/py01.gif")
mon2 = PhotoImage(file="MonsterImages/Converted/py02.gif")
mon3 = PhotoImage(file="MonsterImages/Converted/py03.gif")

#A list of object pictures
monster_images = [mon1, mon2, mon3]

#Set up one label
myLabel=ttk.Label(mainframe, image=mon1)
myLabel.grid(column=1, row=1, sticky=W)


next_image()

root.mainloop()

[toc] | [prev] | [next] | [standalone]


#77332

Fromtheteacher.info@gmail.com
Date2014-08-30 13:27 -0700
Message-ID<f91837e5-2905-4e4a-b174-159f945de11d@googlegroups.com>
In reply to#77319
Although getting next_image to run for e.g. 10 times in a for loop is still something I can't get to work. It only displays one image.

[toc] | [prev] | [next] | [standalone]


#77335

From"Albert Visser" <albert.visser@gmail.com>
Date2014-08-30 22:49 +0200
Message-ID<mailman.13653.1409433077.18130.python-list@python.org>
In reply to#77332
On Sat, 30 Aug 2014 22:27:01 +0200, <theteacher.info@gmail.com> wrote:

> Although getting next_image to run for e.g. 10 times in a for loop is  
> still something I can't get to work. It only displays one image.

I think this is because you do all your processing befoe starting the  
event loop (myGui.mainloop() ).

A better way is to bind the function that displays the images to a button  
callback.
Referring to your first post, that could be something like (untested)

def rotate():
     for i in range(10):
         myImage = PhotoImage(file="MonsterImages/Converted/" +  
random.choice(monsters))
         myButton1.config(image=myImage, width="100", height="200")
         sleep(0.2)

myButton1=Button(canvas1, text='OK', justify = LEFT, command=rotate)
myButton1.place(x=500,y=300)

myGui.mainloop()

Hope this helps
-- 
Vriendelijke groeten / Kind regards,

Albert Visser

Using Opera's mail client: http://www.opera.com/mail/

[toc] | [prev] | [next] | [standalone]


#77334

Fromtheteacher.info@gmail.com
Date2014-08-30 13:37 -0700
Message-ID<7eedecff-7ff3-43f5-ae47-7283f115cad2@googlegroups.com>
In reply to#77319
How do you exit from this function?

def next_image(): 
    myLabel.config(image=random.choice(monster_images)) 
    # tell tkinter to invoke next_image() again after 200 miliseconds 
    root.after(200, next_image)

[toc] | [prev] | [next] | [standalone]


#77336

FromPeter Otten <__peter__@web.de>
Date2014-08-30 23:14 +0200
Message-ID<mailman.13654.1409433267.18130.python-list@python.org>
In reply to#77334
theteacher.info@gmail.com wrote:

> How do you exit from this function?
> 
> def next_image():
>     myLabel.config(image=random.choice(monster_images))
>     # tell tkinter to invoke next_image() again after 200 miliseconds

You misunderstand. The problem with the function is not that it doesn't 
exit, it's just that with

>     root.after(200, next_image)

it schedules itself to be reinvoked by tkinter after 200 seconds. If you 
want to limit that to 10 times instead of indefinitely you can introduce a 
counter:

n = 10
def next_image():
    global n

    myLabel.config(image=random.choice(monster_images))
    n -= 1
    if n > 0:
        root.after(200, next_image)
              


[toc] | [prev] | [next] | [standalone]


#77346

Fromtheteacher.info@gmail.com
Date2014-08-31 02:51 -0700
Message-ID<1472aa15-e0a6-4272-92e6-980f8a8256c5@googlegroups.com>
In reply to#77336
Okay. Got it now. Your help is much appreciated. Thanks.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web