{"id":1746,"date":"2020-12-21T07:01:16","date_gmt":"2020-12-21T07:01:16","guid":{"rendered":"https:\/\/www.pythontutorial.net\/?page_id=1746"},"modified":"2025-04-05T03:41:51","modified_gmt":"2025-04-05T03:41:51","slug":"tkinter-thread","status":"publish","type":"page","link":"https:\/\/www.pythontutorial.net\/tkinter\/tkinter-thread\/","title":{"rendered":"Tkinter Thread"},"content":{"rendered":"\r\n<p><strong>Summary<\/strong>: In this tutorial, you&#8217;ll learn how to use multiple threads in Tkinter applications to make them more responsive.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id='when-to-use-tkinter-with-threads'>When to use Tkinter with Threads <a href=\"#when-to-use-tkinter-with-threads\" class=\"anchor\" id=\"when-to-use-tkinter-with-threads\" title=\"Anchor for When to use Tkinter with Threads\">#<\/a><\/h2>\r\n\r\n\r\n\r\n<p>Let&#8217;s start with a simple program:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> tkinter <span class=\"hljs-keyword\">as<\/span> tk\r\n<span class=\"hljs-keyword\">from<\/span> tkinter <span class=\"hljs-keyword\">import<\/span> ttk\r\n<span class=\"hljs-keyword\">import<\/span> time\r\n\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">task<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\r\n    <span class=\"hljs-comment\"># Simulate a long-running task<\/span>\r\n    <span class=\"hljs-keyword\">for<\/span> i <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">5<\/span>):\r\n        print(<span class=\"hljs-string\">f\"Task running... <span class=\"hljs-subst\">{i+<span class=\"hljs-number\">1<\/span>}<\/span>\/5\"<\/span>)\r\n        time.sleep(<span class=\"hljs-number\">1<\/span>)  \r\n\r\n    print(<span class=\"hljs-string\">\"Task completed!\"<\/span>)\r\n\r\nroot = tk.Tk()\r\nroot.geometry(<span class=\"hljs-string\">\"300x100\"<\/span>)\r\nroot.title(<span class=\"hljs-string\">\"Tkinter Thread Example\"<\/span>)\r\n\r\nbutton = ttk.Button(root, text=<span class=\"hljs-string\">\"Start Thread\"<\/span>, command=task)\r\nbutton.pack(pady=<span class=\"hljs-number\">10<\/span>)\r\n\r\nroot.mainloop()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>How it works.<\/p>\r\n\r\n\r\n\r\n<p>First, define the <code>task()<\/code> function that takes 5 seconds to finish:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">task<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\r\n    <span class=\"hljs-comment\"># Simulate a long-running task<\/span>\r\n    <span class=\"hljs-keyword\">for<\/span> i <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">5<\/span>):\r\n        print(<span class=\"hljs-string\">f\"Task running... <span class=\"hljs-subst\">{i+<span class=\"hljs-number\">1<\/span>}<\/span>\/5\"<\/span>)\r\n        time.sleep(<span class=\"hljs-number\">1<\/span>)  \r\n\r\n    print(<span class=\"hljs-string\">\"Task completed!\"<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Second, create a <a href=\"https:\/\/www.pythontutorial.net\/tkinter\/tkinter-window\/\">main window<\/a> with a <a href=\"https:\/\/www.pythontutorial.net\/tkinter\/tkinter-button\/\">button<\/a>:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">root = tk.Tk()\r\nroot.geometry(<span class=\"hljs-string\">\"300x100\"<\/span>)\r\nroot.title(<span class=\"hljs-string\">\"Tkinter Thread Example\"<\/span>)\r\n\r\nbutton = ttk.Button(\r\n    root, \r\n    text=<span class=\"hljs-string\">\"Start Thread\"<\/span>, \r\n    command=task\r\n)\r\nbutton.pack(padx=<span class=\"hljs-number\">10<\/span> ,pady=<span class=\"hljs-number\">10<\/span>)\r\n\r\nroot.mainloop()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>When you click the button, the program executes the <code>task<\/code> function. During the function execution, the program freezes. It means that you cannot interact with the program by moving the window or clicking the button:<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"306\" height=\"136\" class=\"wp-image-7514\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2025\/04\/tkinter-thread-freeze-ui.png\" alt=\"\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2025\/04\/tkinter-thread-freeze-ui.png 306w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2025\/04\/tkinter-thread-freeze-ui-300x133.png 300w\" sizes=\"auto, (max-width: 306px) 100vw, 306px\" \/><\/figure>\r\n\r\n\r\n\r\n<p>In Tkinter applications, the main loop should always start in the main thread. It handles events and updates the user interface (UI).<\/p>\r\n\r\n\r\n\r\n<p>If you have an operation that takes time, you should execute it in a separate <a href=\"https:\/\/www.pythontutorial.net\/tkinter\/tkinter-thread\/\">thread<\/a>. To create and control multiple threads in Tkinter applications, you use the built-in <a href=\"https:\/\/www.pythontutorial.net\/advanced-python\/python-threading\/\"><code>threading<\/code><\/a> module.<\/p>\r\n\r\n\r\n\r\n<p class=\"note\">For more information on how to use the threading module, you can follow the <a href=\"https:\/\/www.pythontutorial.net\/advanced-python\/python-threading\/\">Python threading tutorial<\/a>.<\/p>\r\n\r\n\r\n\r\n<p>The following program shows how to execute the <code>task<\/code> function in a separate thread:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> tkinter <span class=\"hljs-keyword\">as<\/span> tk\r\n<span class=\"hljs-keyword\">from<\/span> tkinter <span class=\"hljs-keyword\">import<\/span> ttk\r\n<span class=\"hljs-keyword\">import<\/span> time\r\n<span class=\"hljs-keyword\">from<\/span> threading <span class=\"hljs-keyword\">import<\/span> Thread\r\n\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">task<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\r\n    <span class=\"hljs-comment\"># Simulate a long-running task<\/span>\r\n    <span class=\"hljs-keyword\">for<\/span> i <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">5<\/span>):\r\n        print(<span class=\"hljs-string\">f\"Task running... <span class=\"hljs-subst\">{i+<span class=\"hljs-number\">1<\/span>}<\/span>\/5\"<\/span>)\r\n        time.sleep(<span class=\"hljs-number\">1<\/span>)  \r\n\r\n    print(<span class=\"hljs-string\">\"Task completed!\"<\/span>)\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">handle_click<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\r\n    t = Thread(target=task)\r\n    t.start()\r\n    \r\n\r\nroot = tk.Tk()\r\nroot.geometry(<span class=\"hljs-string\">\"300x100\"<\/span>)\r\nroot.title(<span class=\"hljs-string\">\"Tkinter Thread Example\"<\/span>)\r\n\r\nbutton = ttk.Button(\r\n    root, \r\n    text=<span class=\"hljs-string\">\"Start Thread\"<\/span>, \r\n    command=handle_click\r\n)\r\nbutton.pack(padx=<span class=\"hljs-number\">10<\/span> ,pady=<span class=\"hljs-number\">10<\/span>)\r\n\r\nroot.mainloop()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>How it works:<\/p>\r\n\r\n\r\n\r\n<p>First, import the <code><a href=\"https:\/\/www.pythontutorial.net\/python-concurrency\/python-threading\/\">Thread<\/a><\/code> class from the <code>threading<\/code> module:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> threading <span class=\"hljs-keyword\">import<\/span> Thread<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Second, define a function <code>handle_click<\/code> that creates a new thread and starts it:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">handle_click<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\r\n    t = Thread(target=task)\r\n    t.start()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>The new thread will execute the <code>task<\/code> function.<\/p>\r\n\r\n\r\n\r\n<p>Third, bind the <code>handle_click<\/code> function to the command of the button:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">button = ttk.Button(\r\n    root, \r\n    text=<span class=\"hljs-string\">\"Start Thread\"<\/span>, \r\n    command=handle_click\r\n)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>If you run the program and click the button, it will create two threads:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>The main thread is responsible for updating the user interface.<\/li>\r\n\r\n\r\n\r\n<li>A second thread executes the <code>task<\/code> function.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p>Since the <code>task<\/code> function does not block the main thread, you can interact with the program like moving main window. It does not freeze like before.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id='getting-values-from-threads'>Getting values from threads <a href=\"#getting-values-from-threads\" class=\"anchor\" id=\"getting-values-from-threads\" title=\"Anchor for Getting values from threads\">#<\/a><\/h2>\r\n\r\n\r\n\r\n<p>To get value from a thread, you follow these steps:<\/p>\r\n\r\n\r\n\r\n<p>First, define a new class that extends the <code>Thread<\/code> class and define additional attributes you want to access after the thread finishes:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CustomThread<\/span><span class=\"hljs-params\">(Thread)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        super().__init__()\r\n        self.result = <span class=\"hljs-literal\">None<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Second, override the <code>run()<\/code> method of the <code>Thread<\/code> class, execute a task, and update the result:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">run<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n   <span class=\"hljs-comment\"># execute a task <\/span>\r\n   <span class=\"hljs-comment\"># update the result<\/span>\r\n   self.result = return_value<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>For example, the following program shows how to get a random number in a separate thread and display the result on the main window:<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"406\" height=\"166\" class=\"wp-image-7516\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2025\/04\/tkinter-thread-getting-a-value.png\" alt=\"\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2025\/04\/tkinter-thread-getting-a-value.png 406w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2025\/04\/tkinter-thread-getting-a-value-300x123.png 300w\" sizes=\"auto, (max-width: 406px) 100vw, 406px\" \/><\/figure>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> tkinter <span class=\"hljs-keyword\">as<\/span> tk\r\n<span class=\"hljs-keyword\">from<\/span> tkinter <span class=\"hljs-keyword\">import<\/span> ttk\r\n<span class=\"hljs-keyword\">import<\/span> time\r\n<span class=\"hljs-keyword\">from<\/span> threading <span class=\"hljs-keyword\">import<\/span> Thread\r\n<span class=\"hljs-keyword\">import<\/span> random\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RandomNumber<\/span><span class=\"hljs-params\">(Thread)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        super().__init__()\r\n        self.result = <span class=\"hljs-literal\">None<\/span>\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">run<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">for<\/span> i <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">3<\/span>):\r\n            print(<span class=\"hljs-string\">f\"Thread running... <span class=\"hljs-subst\">{i+<span class=\"hljs-number\">1<\/span>}<\/span>\/5\"<\/span>)           \r\n            time.sleep(<span class=\"hljs-number\">1<\/span>)\r\n\r\n        print(<span class=\"hljs-string\">\"Thread completed!\"<\/span>)\r\n        self.result = random.randint(<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">100<\/span>)  \r\n\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">App<\/span><span class=\"hljs-params\">(tk.Tk)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        super().__init__()\r\n        self.geometry(<span class=\"hljs-string\">\"400x130\"<\/span>)\r\n        self.title(<span class=\"hljs-string\">\"Tkinter Thread Example\"<\/span>)\r\n\r\n        <span class=\"hljs-comment\"># Create a label to display the result<\/span>\r\n        self.result_var = tk.StringVar()\r\n        self.label = ttk.Label(\r\n            self, \r\n            text=<span class=\"hljs-string\">\"Result will appear here\"<\/span>, \r\n            font=(<span class=\"hljs-string\">\"TkDefaultFont\"<\/span>, <span class=\"hljs-number\">24<\/span>),\r\n            textvariable=self.result_var\r\n        )\r\n        self.label.pack(padx=<span class=\"hljs-number\">10<\/span> ,pady=<span class=\"hljs-number\">10<\/span>)\r\n\r\n        <span class=\"hljs-comment\"># Create a button to start the thread<\/span>\r\n        self.button = ttk.Button(\r\n            self, \r\n            text=<span class=\"hljs-string\">\"Get a Random Number\"<\/span>, \r\n            command=self.handle_click\r\n        )\r\n        self.button.pack(padx=<span class=\"hljs-number\">10<\/span> ,pady=<span class=\"hljs-number\">10<\/span>)\r\n\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">handle_click<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        thread = RandomNumber()\r\n        thread.start()\r\n        self.monitor(thread)\r\n        \r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">monitor<\/span><span class=\"hljs-params\">(self, thread)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> thread.is_alive():\r\n            self.after(<span class=\"hljs-number\">100<\/span>, <span class=\"hljs-keyword\">lambda<\/span>: self.monitor(thread))\r\n        <span class=\"hljs-keyword\">else<\/span>:\r\n            self.result_var.set(thread.result)\r\n        \r\n\r\n<span class=\"hljs-keyword\">if<\/span> __name__ == <span class=\"hljs-string\">\"__main__\"<\/span>:\r\n    app = App()\r\n    app.mainloop()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>How it works.<\/p>\r\n\r\n\r\n\r\n<p>First, define the <code>RandomNumber<\/code> class that extends the <code>Thread<\/code> class:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RandomNumber<\/span><span class=\"hljs-params\">(Thread)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        super().__init__()\r\n        self.result = <span class=\"hljs-literal\">None<\/span>\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">run<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">for<\/span> i <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">3<\/span>):\r\n            print(<span class=\"hljs-string\">f\"Thread running... <span class=\"hljs-subst\">{i+<span class=\"hljs-number\">1<\/span>}<\/span>\/5\"<\/span>)           \r\n            time.sleep(<span class=\"hljs-number\">1<\/span>)\r\n\r\n        print(<span class=\"hljs-string\">\"Thread completed!\"<\/span>)\r\n        self.result = random.randint(<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">100<\/span>) <\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>We use the sleep() function in the run method to simulate a long-running operation. The run method takes 3 seconds before returning a random number between 1 and 100. Once the thread completes, we assign the random number to the result attribute.<\/p>\r\n\r\n\r\n\r\n<p>Second, define the App class that extends the Tk class:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">App<\/span><span class=\"hljs-params\">(tk.Tk)<\/span>:<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>When you click the button, the handle_click method executes that:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Start a new <code>RandomNumber<\/code> thread.<\/li>\r\n\r\n\r\n\r\n<li>Call the monitor method to check if the thread is still running.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p>The <code>monitor<\/code> method checks the thread every 100 milliseconds. If the thread is not alive, it updates the <code>result_var<\/code> with the <code>result<\/code> of the <code>RandomNumber<\/code> thread:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">monitor<\/span><span class=\"hljs-params\">(self, thread)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> thread.is_alive():\r\n            self.after(<span class=\"hljs-number\">100<\/span>, <span class=\"hljs-keyword\">lambda<\/span>: self.monitor(thread))\r\n        <span class=\"hljs-keyword\">else<\/span>:\r\n            self.result_var.set(thread.result)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Once the value of the <code>result_var<\/code> object changes, it automatically updates the label on the main window.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id='enhancing-ui'>Enhancing UI <a href=\"#enhancing-ui\" class=\"anchor\" id=\"enhancing-ui\" title=\"Anchor for Enhancing UI\">#<\/a><\/h2>\r\n\r\n\r\n\r\n<p>You can click the button to start another thread when the thread is running. This is not what we want. To prevent users from clicking the button when the thread is running, we can enhance the user interface:<\/p>\r\n\r\n\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Disable the button when the thread starts.<\/li>\r\n\r\n\r\n\r\n<li>Enable the button when the thread completes.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p>Additionally, we can change the label to indicate the program is running like &#8216;Processing&#8230;&#8217;.<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"366\" height=\"195\" class=\"wp-image-7517\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2025\/04\/Tkinter-Thread.gif\" alt=\"Tkinter Thread\" \/><\/figure>\r\n\r\n\r\n\r\n<p>The following program illustrates these improvements:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> tkinter <span class=\"hljs-keyword\">as<\/span> tk\r\n<span class=\"hljs-keyword\">from<\/span> tkinter <span class=\"hljs-keyword\">import<\/span> ttk\r\n<span class=\"hljs-keyword\">import<\/span> time\r\n<span class=\"hljs-keyword\">from<\/span> threading <span class=\"hljs-keyword\">import<\/span> Thread\r\n<span class=\"hljs-keyword\">import<\/span> random\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RandomNumber<\/span><span class=\"hljs-params\">(Thread)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        super().__init__()\r\n        self.result = <span class=\"hljs-literal\">None<\/span>\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">run<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">for<\/span> i <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">3<\/span>):\r\n            print(<span class=\"hljs-string\">f\"Thread running... <span class=\"hljs-subst\">{i+<span class=\"hljs-number\">1<\/span>}<\/span>\/5\"<\/span>)           \r\n            time.sleep(<span class=\"hljs-number\">1<\/span>)\r\n\r\n        print(<span class=\"hljs-string\">\"Thread completed!\"<\/span>)\r\n        self.result = random.randint(<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">100<\/span>)  \r\n\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">App<\/span><span class=\"hljs-params\">(tk.Tk)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        super().__init__()\r\n        self.geometry(<span class=\"hljs-string\">\"400x130\"<\/span>)\r\n        self.title(<span class=\"hljs-string\">\"Tkinter Thread Example\"<\/span>)\r\n\r\n        <span class=\"hljs-comment\"># Create a label to display the result<\/span>\r\n        self.result_var = tk.StringVar()\r\n        self.label = ttk.Label(\r\n            self, \r\n            text=<span class=\"hljs-string\">\"Result will appear here\"<\/span>, \r\n            font=(<span class=\"hljs-string\">\"TkDefaultFont\"<\/span>, <span class=\"hljs-number\">24<\/span>),\r\n            textvariable=self.result_var\r\n        )\r\n        self.label.pack(padx=<span class=\"hljs-number\">10<\/span> ,pady=<span class=\"hljs-number\">10<\/span>)\r\n\r\n        <span class=\"hljs-comment\"># Create a button to start the thread<\/span>\r\n        self.button = ttk.Button(\r\n            self, \r\n            text=<span class=\"hljs-string\">\"Get a Random Number\"<\/span>, \r\n            command=self.handle_click\r\n        )\r\n        self.button.pack(padx=<span class=\"hljs-number\">10<\/span> ,pady=<span class=\"hljs-number\">10<\/span>)\r\n\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">handle_click<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-comment\"># Disable the button to prevent multiple clicks<\/span>\r\n        self.button.config(state=tk.DISABLED)\r\n        self.result_var.set(<span class=\"hljs-string\">\"Processing...\"<\/span>)\r\n\r\n        <span class=\"hljs-comment\"># Start the thread<\/span>\r\n        thread = RandomNumber()\r\n        thread.start()\r\n        \r\n        <span class=\"hljs-comment\"># Monitor the thread<\/span>\r\n        self.monitor(thread)\r\n        \r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">monitor<\/span><span class=\"hljs-params\">(self, thread)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> thread.is_alive():\r\n            self.after(<span class=\"hljs-number\">100<\/span>, <span class=\"hljs-keyword\">lambda<\/span>: self.monitor(thread))\r\n        <span class=\"hljs-keyword\">else<\/span>:\r\n            <span class=\"hljs-comment\"># Show the result<\/span>\r\n            self.result_var.set(thread.result)\r\n            <span class=\"hljs-comment\"># Enable the button again<\/span>\r\n            self.button.config(state=tk.NORMAL)\r\n        \r\n<span class=\"hljs-keyword\">if<\/span> __name__ == <span class=\"hljs-string\">\"__main__\"<\/span>:\r\n    app = App()\r\n    app.mainloop()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>First, disable the button and change the label to <code>\"Processing...\"<\/code> before starting a new thread:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">handle_click<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n  <span class=\"hljs-comment\"># Disable the button to prevent multiple clicks<\/span>\r\n  self.button.config(state=tk.DISABLED)\r\n  self.result_var.set(<span class=\"hljs-string\">\"Processing...\"<\/span>)\r\n\r\n  <span class=\"hljs-comment\"># Start the thread<\/span>\r\n  thread = RandomNumber()\r\n  thread.start()\r\n  \r\n  <span class=\"hljs-comment\"># Monitor the thread<\/span>\r\n  self.monitor(thread)   <\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Second, enable the button when the thread completes:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">monitor<\/span><span class=\"hljs-params\">(self, thread)<\/span>:<\/span>\r\n    <span class=\"hljs-keyword\">if<\/span> thread.is_alive():\r\n        self.after(<span class=\"hljs-number\">100<\/span>, <span class=\"hljs-keyword\">lambda<\/span>: self.monitor(thread))\r\n    <span class=\"hljs-keyword\">else<\/span>:\r\n        <span class=\"hljs-comment\"># Show the result<\/span>\r\n        self.result_var.set(thread.result)\r\n        <span class=\"hljs-comment\"># Enable the button again<\/span>\r\n        self.button.config(state=tk.NORMAL)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id='adding-a-progressbar'>Adding a Progressbar <a href=\"#adding-a-progressbar\" class=\"anchor\" id=\"adding-a-progressbar\" title=\"Anchor for Adding a Progressbar\">#<\/a><\/h2>\r\n\r\n\r\n\r\n<p>We can improve the program by adding a <a href=\"https:\/\/www.pythontutorial.net\/tkinter\/tkinter-progressbar\/\">Progressbar<\/a> widget to it:<\/p>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"371\" height=\"209\" class=\"wp-image-7520\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2025\/04\/Tkinter-Thread-with-a-progress-bar.gif\" alt=\"Tkinter Thread with a progress bar\" \/><\/figure>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> tkinter <span class=\"hljs-keyword\">as<\/span> tk\r\n<span class=\"hljs-keyword\">from<\/span> tkinter <span class=\"hljs-keyword\">import<\/span> ttk\r\n<span class=\"hljs-keyword\">import<\/span> time\r\n<span class=\"hljs-keyword\">from<\/span> threading <span class=\"hljs-keyword\">import<\/span> Thread\r\n<span class=\"hljs-keyword\">import<\/span> random\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RandomNumber<\/span><span class=\"hljs-params\">(Thread)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        super().__init__()\r\n        self.result = <span class=\"hljs-literal\">None<\/span>\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">run<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">for<\/span> i <span class=\"hljs-keyword\">in<\/span> range(<span class=\"hljs-number\">3<\/span>):\r\n            print(<span class=\"hljs-string\">f\"Thread running... <span class=\"hljs-subst\">{i+<span class=\"hljs-number\">1<\/span>}<\/span>\/5\"<\/span>)           \r\n            time.sleep(<span class=\"hljs-number\">1<\/span>)\r\n\r\n        print(<span class=\"hljs-string\">\"Thread completed!\"<\/span>)\r\n        self.result = random.randint(<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">100<\/span>)  \r\n\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">App<\/span><span class=\"hljs-params\">(tk.Tk)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        super().__init__()\r\n        self.geometry(<span class=\"hljs-string\">\"400x150\"<\/span>)\r\n        self.title(<span class=\"hljs-string\">\"Tkinter Thread Example\"<\/span>)\r\n\r\n        <span class=\"hljs-comment\"># Create a label to display the result<\/span>\r\n        self.result_var = tk.StringVar()\r\n        self.label = ttk.Label(\r\n            self, \r\n            text=<span class=\"hljs-string\">\"Result will appear here\"<\/span>, \r\n            font=(<span class=\"hljs-string\">\"TkDefaultFont\"<\/span>, <span class=\"hljs-number\">24<\/span>),\r\n            textvariable=self.result_var\r\n        )\r\n        self.label.pack(padx=<span class=\"hljs-number\">10<\/span> ,pady=<span class=\"hljs-number\">10<\/span>)\r\n\r\n        <span class=\"hljs-comment\"># Create a progress bar<\/span>\r\n        self.progress_bar = ttk.Progressbar(self, mode=<span class=\"hljs-string\">'indeterminate'<\/span>)\r\n\r\n        <span class=\"hljs-comment\"># Create a button to start the thread<\/span>\r\n        self.button = ttk.Button(\r\n            self, \r\n            text=<span class=\"hljs-string\">\"Get a Random Number\"<\/span>, \r\n            command=self.handle_click\r\n        )\r\n        self.button.pack(padx=<span class=\"hljs-number\">10<\/span> ,pady=<span class=\"hljs-number\">10<\/span>)\r\n        \r\n\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">handle_click<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-comment\"># Disable the button to prevent multiple clicks<\/span>\r\n        self.button.config(state=tk.DISABLED)\r\n        self.result_var.set(<span class=\"hljs-string\">\"Processing...\"<\/span>)\r\n\r\n        <span class=\"hljs-comment\"># Show the progress bar<\/span>\r\n        self.progress_bar.pack(padx=<span class=\"hljs-number\">10<\/span>, pady=<span class=\"hljs-number\">10<\/span>, fill=tk.X, expand=<span class=\"hljs-literal\">True<\/span>)\r\n        self.progress_bar.start()\r\n\r\n        self.result_var.set(<span class=\"hljs-string\">\"Processing...\"<\/span>)\r\n\r\n        <span class=\"hljs-comment\"># Start the thread<\/span>\r\n        thread = RandomNumber()\r\n        thread.start()\r\n\r\n        <span class=\"hljs-comment\"># Monitor the thread<\/span>\r\n        self.monitor(thread)\r\n        \r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">monitor<\/span><span class=\"hljs-params\">(self, thread)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> thread.is_alive():\r\n            self.after(<span class=\"hljs-number\">100<\/span>, <span class=\"hljs-keyword\">lambda<\/span>: self.monitor(thread))\r\n        <span class=\"hljs-keyword\">else<\/span>:\r\n            \r\n            <span class=\"hljs-comment\"># Hide the progress bar<\/span>\r\n            self.progress_bar.stop()\r\n            self.progress_bar.pack_forget()\r\n\r\n            <span class=\"hljs-comment\"># Enable the button again<\/span>\r\n            self.button.config(state=tk.NORMAL)\r\n\r\n            <span class=\"hljs-comment\"># Display the result<\/span>\r\n            self.result_var.set(thread.result)\r\n        \r\n\r\n<span class=\"hljs-keyword\">if<\/span> __name__ == <span class=\"hljs-string\">\"__main__\"<\/span>:\r\n    app = App()\r\n    app.mainloop()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>How it works.<\/p>\r\n\r\n\r\n\r\n<p>First, create a <code>Progressbar<\/code> widget in the <code>__init__<\/code> method of the <code>App<\/code> class:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">self.progress_bar = ttk.Progressbar(self, mode=<span class=\"hljs-string\">'indeterminate'<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Second, show the <code>Progressbar<\/code> widget and start it in the <code>handle_click<\/code> button method before starting a new thread:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">self.progress_bar.pack(padx=<span class=\"hljs-number\">10<\/span>, pady=<span class=\"hljs-number\">10<\/span>, fill=tk.X, expand=<span class=\"hljs-literal\">True<\/span>)\r\nself.progress_bar.start()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<p>Third, stop the <code>Progressbar<\/code> and hide it after the thread completes in the <code>monitor()<\/code> method:<\/p>\r\n\r\n\r\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">self.progress_bar.stop()\r\nself.progress_bar.pack_forget()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\r\n\r\n\r\n<h2 class=\"wp-block-heading\" id='summary'>Summary <a href=\"#summary\" class=\"anchor\" id=\"summary\" title=\"Anchor for Summary\">#<\/a><\/h2>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Execute long-running tasks in separate threads to make Tkinter programs responsive.<\/li>\r\n<\/ul>\r\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"1746\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/tkinter\/tkinter-thread\/\"\n\t\t\t\tdata-post-title=\"Tkinter Thread\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"1746\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/tkinter\/tkinter-thread\/\"\n\t\t\t\tdata-post-title=\"Tkinter Thread\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\t\t\t<input type=\"button\" name=\"wth-submit\" class=\"wth-btn wth-btn-submit\" id=\"wth-submit\" \/>\n\t\t\t<input type=\"button\" class=\"wth-btn wth-btn-cancel\" value=\"Cancel\" \/>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn how to use multiple threads in Tkinter applications to make the applications more responsive.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1232,"menu_order":53,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1746","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/1746","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/comments?post=1746"}],"version-history":[{"count":4,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/1746\/revisions"}],"predecessor-version":[{"id":7523,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/1746\/revisions\/7523"}],"up":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/1232"}],"wp:attachment":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/media?parent=1746"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}