简体   繁体   中英

How to make the text in a button quickly change repeatedly using tkinter

I am trying to make a graphical slot machine and am currently working on trying to make the slots "spin". However the buttons seem to skip all other changes and go straight to the final value. I have tried using time.sleep but this too doesn't work. Currently I am looping through a second function but still does not work. How can I ensure the buttons show all values they have taken throughout the looping process?

Here is the code below:

import tkinter as tk,random,time

root=tk.Tk()

results=["@","!","$","W","*","£","#","X","%"]

class spin:
    def __init__(self,rowa,columna,text):
        self.text=text
        self=tk.Button(root, height=1,width=2,text=text)
        self.grid(row=rowa,column=columna)

class spun:
    def __init__(self,rowa,columna,text,com):
        self.text=text
        self=tk.Button(root, height=1,width=15,text=self.text,command=com)
        self.grid(row=rowa,column=columna, columnspan=5)

def rotate():
    for i in range(0,10):
        part2()
        time.sleep(0.00005)


def part2():
    global slot1,slot2,slot3,slot4,slot5
    slot1=spin(1,0,results[random.randint(0,len(results)-1)])
    slot2=spin(1,1,results[random.randint(0,len(results)-1)])
    slot3=spin(1,2,results[random.randint(0,len(results)-1)])
    slot4=spin(1,3,results[random.randint(0,len(results)-1)])
    slot5=spin(1,4,results[random.randint(0,len(results)-1)])




slot1=spin(1,0,"@")
slot2=spin(1,1,"£")
slot3=spin(1,2,"%")
slot4=spin(1,3,"$")
slot5=spin(1,4,"#")

spinner=spun(2,0,"Spin",rotate)

root.mainloop()

As stated in the comments, the key is to use update_idletasks() in the for loop to force the GUI to update at each iteration.

Below is a suggestion about how to structure your code. Instead of using global slot1, ... you could create a class for your slot machine. As indicated in the comments you don't need to recreate the buttons at each iteration in rotate() , you just need to change their texts with .configure(text=<new value>) . Finally I used random.choices() to directly draw a random value in a list instead of drawing the item's index with random.randint() .

import tkinter as tk
import random


class Spinner(tk.Frame):
    def __init__(self, master, results, **kw):
        tk.Frame.__init__(self, master, **kw)
        self.results = results

        self.slots = []
        for i in range(5):
            b = tk.Button(self, height=1, width=2, text=self.results[i])
            b.grid(row=0, column=i)
            self.slots.append(b)

        tk.Button(self, height=1, width=15, text='Spin',
                  command=self.rotate).grid(row=1, columnspan=5)

    def rotate(self):
        for i in range(0, 10):
            for slot in self.slots:
                slot.configure(text=random.choices(self.results))
            self.update_idletasks()  # force GUI to update
            self.after(5)  # tkinter method which pause the GUI, the time is given in ms
                           # it can also be use to schedule a function call (see Tkinter doc)


root = tk.Tk()
results = ["@", "!", "$", "W", "*", "£", "#", "X", "%"]

spinner = Spinner(root, results)
spinner.pack()

root.mainloop()

Note: you might want to have a look at the style guideline PEP 8 which helps writing clear python code (eg they advise to capitalize class names, put one space after a comma, ...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM