unknow_user
unknow_user

Reputation: 35

Python - tkinter button freeze

I have problem with freezing application in Python. I used tkinter library to make some app. When I using Send button it calls the functions that lasts 3 minutes and freezing application on this 3 minutes... I want to see all logs from this function "live". I can't wait 3 minutes and then get all the logs.

Below is example of my code:

import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext
import time


class Frames:

    def main_frame(self, win):

        # Main Frame
        main = ttk.LabelFrame(win, text="")
        main.grid(column=0, row=0, sticky="WENS", padx=10, pady=10)
        return main

    def button_frame(self, win):

        # Button Frame
        butt_frame = ttk.LabelFrame(win, text="Button")
        butt_frame.grid(column=0, row=0, sticky='NWS')

        def _send_button():
            for i in range(10):
                self.write_text_console("{0}\n".format(i))
                time.sleep(0.5)

        # Send Button
        ttk.Label(butt_frame, text="                                         ").grid(column=0, row=8)
        button = tk.Button(butt_frame, text="Send", command=_send_button, foreground='black')
        button.grid(column=0, row=13, sticky=tk.EW)

    def scrolled_text_widget(self, win):
        ttk.Label(win, text="                                         ").grid(column=0, row=1)
        ttk.Label(win, text="Console Output:").grid(column=0, row=2, sticky=tk.W)
        self.scr = scrolledtext.ScrolledText(win, width=100, height=10, wrap=tk.WORD, state="disabled")
        self.scr.grid(column=0, row=3, columnspan=5)

    def write_text_console(self, string, color="black", tag="console"):
        self.scr.configure(state='normal')
        self.scr.insert('end', string, tag)
        self.scr.tag_config(tag, foreground=color)
        self.scr.configure(state='disabled')
        self.scr.see("end")


win = tk.Tk()
win.geometry("845x300")
win.resizable(0, 0)
frames = Frames()
main = frames.main_frame(win)
frames.button_frame(main)
frames.scrolled_text_widget(main)
win.mainloop()

This example showing my problem. When you click the Send button it freeze app for 5s. But I need to see the logs during the loop.

How can I resolve it?

Upvotes: 2

Views: 1011

Answers (3)

Lewis
Lewis

Reputation: 524

In Tkinter the GUI runs in the same thread of the application code including event handlers. And because it is single-threaded, event handlers must respond quickly, otherwise they will block other events from being processed.
You should avoid doing long-running computations in an event handler, break them into smaller pieces using timers or run in another thread.
That said, here is a simple solution for your problem.

def _send_button():
    for i in range(10):
        self.write_text_console("{0}\n".format(i))
        win.update_idletasks()
        time.sleep(0.5)

Upvotes: 0

codewithdev
codewithdev

Reputation: 46

To freeze the button, add state= DISABLED in the specific button widget.

from tkinter import *

#Create an instance of tkiner frame
root= Tk()

#Define the geometry of the function
root.geometry("400x250")

Button(root, text="OK", state= DISABLED).pack(pady=20)

root.mainloop()

Upvotes: 0

Muhammad Yousuf Noor
Muhammad Yousuf Noor

Reputation: 197

Tkinter is running a loop in your main thread, that's why your app freezes when you click on a button. The solution is to create a new thread.

1- You have to import threading

import threading

2- Start a new thread in your _send_button() function. It should be like this.

 def _send_button():

        def click_button():
            for i in range(10):
                self.write_text_console("{0}\n".format(i))
                time.sleep(0.5)

        threading.Thread(target=click_button).start()

Learn More About Threading In Python

Upvotes: 4

Related Questions