Rt Rtt
Rt Rtt

Reputation: 617

Why after() method not works in a multi for loop?

I am going to use the after() method in a multi forloop. The plan is to print every combined text at interval of one second.

But it runs directly to the end and only prints the last combined text. How can I fix this?

Here is my code:

# -*- coding: utf-8 -*-

from Tkinter import *
import time

FirstList = ["1", "2", "3", "4"]
SecondList = ["a", "b", "c", "d", "e", "f"]
ThirdList = ["A" , "B" , "C"]

root = Tk()
root.title("Program")
root['background'] ='gray'

def command_Print():
    for i in range(0, len(FirstList), 1):
        for j in range(0, len(SecondList), 1):
            for k in range(0, len(ThirdList), 1):
                PrintText = FirstList[i] + SecondList[j] + ThirdList[k]
                Labelvar.set(PrintText)
                Label0.after(1000, lambda: command_Print)

Labelvar = StringVar()
Labelvar.set(u'original value')
Frame0 = Frame(root)
Frame0.place(x=0, y=0, width=100, height=50)
Label0 = Label(Frame0, textvariable=Labelvar, anchor='w')
Label0.pack(side=LEFT)

Frame_I = Frame(root)
Frame_I.place(x = 100, y = 0, width=100, height=70)
Button_I = Button(Frame_I, text = "Button" , width = 100, height=70, command = command_Print)
Button_I.place(x=0, y=0)
Button_I.grid(row=0, column=0, sticky=W, pady=4)
Button_I.pack()

root.mainloop()

Upvotes: 0

Views: 88

Answers (1)

Pythonista
Pythonista

Reputation: 11635

If I understand what you want, you just want the cartestian product of your lists. You can use itertools for this instead of a nested forloop like you have, no need to re-invent the wheel since itertools already has this built-in and it's by far cleaner.

Here you go: (Not tested)

import itertools

PRODUCTS = itertools.product(FirstList, SecondList, ThirdList)

def show_next_product():

     try:
        LabelVar.set(next(PRODUCTS))
        root.last_after = root.after(1000, show_next_product)
     except StopIteration:
        LabelVar.set("Out of products.")
        root.after_cancel(root.last_after)

Also, the StringVar seems unnecessary. Unless you're doing something with trace method for StringVar's I've never seen the point in using them honestly.

You can just directly change the text by using Label0['text'] = 'newtext', but that's personal preference of course. :)

Upvotes: 3

Related Questions