Abhay Singh
Abhay Singh

Reputation: 1

Tkinter GUI freezing, used Thread then encountered RuntimeError: threads can only be started once

Please help

def change_flag(top_frame, bottom_frame, button1, button2, button3, button4, controller):
    global counter, canvas, my_image, chosen, flag, directory
    canvas.delete('all')
    button5['state'] = DISABLED
    counter += 1

    chosen, options_text = function_options()
    right_answer_flag = get_right_answer_flag(chosen, options_text)
    #pdb.set_trace()

    try:
        location = directory + chosen + format_image
    except:
        controller.show_frame(PlayAgainExit)
        
    my_image = PhotoImage(file=location)
    canvas.create_image(160, 100, anchor=CENTER, image=my_image)

    button1["text"] = options_text[0]
    button2["text"] = options_text[1]
    button3["text"] = options_text[2]
    button4["text"] = options_text[3]

    button1['state'] = NORMAL
    button2['state'] = NORMAL
    button3['state'] = NORMAL
    button4['state'] = NORMAL

##############

        button5 = Button(
            next_frame,
            width=20,
            text="next",
            fg="black",
            #command=lambda: change_flag(top_frame,bottom_frame,button1,button2,button3,button4,controller))
            command=Thread(target=change_flag, args =(top_frame,bottom_frame,button1,button2,button3,button4,controller)).start)
            
        button5.pack(side=RIGHT, padx=5, pady=5)

Hello,

I do not want the GUI to freeze, so I used threading for button5 but then it is giving me the runtime error of "You can start the threads only once" which is correct. But How should I resolve this problem?

Thanks for your help, Abhay

Upvotes: 0

Views: 47

Answers (1)

acw1668
acw1668

Reputation: 47093

command=Thread(target=change_flag, args=(top_frame,bottom_frame,button1,button2,button3,button4,controller)).start

is to create an instance of the thread object and pass the reference of start function of the instance to the command option. It is like below:

# create an instance of the thread object
t = Thread(target=change_flag, args=(top_frame,bottom_frame,button1,button2,button3,button4,controller))
# pass the start function of the thread object to command option
button5 = Button(..., command=t.start)

So when the button is clicked, it starts the thread. When the button is clicked again, the same thread instance is started again which is not allowed.

You can use lambda, so that when the button is clicked, a new instance of the thread object is created and started:

button5 = Button(..., command=lambda: Thread(target=change_flag, args=(top_frame,bottom_frame,button1,button2,button3,button4,controller)).start())

Upvotes: 1

Related Questions