0

I'm trying to write a tkinter program with start and stop buttons. For both the start and stop buttons, I am importing two different functions from different .py files. When I click on the start button, tkinter freezes and my cursor is constantly "processing" and does not let me click on the stop button.

My tkinter program is below:

import tkinter as tk
from start import hello
from stop import quitprog

class Page(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
    def show(self):
        self.lift()

class Page1(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = tk.Label(self, text="Collecting Data Now...")
       label.pack(side="top", fill="both", expand=True)

class Page2(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = tk.Label(self, text="Analyzing Data Now...")
       label.pack(side="top", fill="both", expand=True)


class MainView(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        p1 = Page1(self)
        p2 = Page2(self)

        buttonframe = tk.Frame(self)
        container = tk.Frame(self)
        buttonframe.pack(side="top", fill="x", expand=False)
        container.pack(side="top", fill="both", expand=True)

        p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)


        b1 = tk.Button(buttonframe, text="start", command=hello)
        b2 = tk.Button(buttonframe, text="stop", command=quitprog)

        b1.pack(side="left")
        b2.pack(side="left")

        p1.show()

if __name__ == "__main__":
    root = tk.Tk()
    main = MainView(root)
    main.pack(side="top", fill="both", expand=True)
    root.wm_geometry("400x400")
    root.mainloop()

My start.py is below:

import time
def hello():
    for i in range(20):
        print("hello world")
        time.sleep(1)

My stop.py:

import sys
def quitprog():
    sys.exit()

My frozen window:

loading/processing cursor image

Please let me know how to fix this.

Edit: Instead of the start.py program, I'm actually invoking a live twitter stream and that doesn't make use of .sleep(). Instead, there is a continuous flow of twitter data, which causes the program to freeze. Any fixes for this?

h20
  • 9
  • 2
  • 1
    `time.sleep(1)` does block your code a second and you call it 20 times, that will be 20 seconds of a freezed event loop. What have you expected instead? – Thingamabobs Nov 28 '21 at 12:25
  • Instead of the start.py program, I'm actually invoking a live twitter stream and that doesn't make use of .sleep(). Instead, there is a continuous flow of twitter data. Whenever I click the start button the program freezes and doesn't allow me to click the stop button. Any fixes for this? – h20 Nov 28 '21 at 13:10
  • You will need to make use of another [thread](https://stackoverflow.com/questions/16745507/tkinter-how-to-use-threads-to-preventing-main-event-loop-from-freezing). – Thingamabobs Nov 28 '21 at 13:23

1 Answers1

0

You need to use multithreading. Simplest to use (in my opinion) is the standard library multiprocessing module:

import multiprocessing

...


class MainView(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        p1 = Page1(self)
        p2 = Page2(self)

        buttonframe = tk.Frame(self)
        container = tk.Frame(self)
        buttonframe.pack(side="top", fill="x", expand=False)
        container.pack(side="top", fill="both", expand=True)

        p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)


        b1 = tk.Button(buttonframe, text="start", command=self.hello)
        b2 = tk.Button(buttonframe, text="stop", command=quitprog)

        b1.pack(side="left")
        b2.pack(side="left")

        p1.show()
    
    def hello(self, *args):
        p = multiprocessing.Process(target=hello)
        p.start()

quitprog does not need to be run in a separate process,and can't be either, because then sys.exit won't terminate your program. I only included the MainView class code - make sure to add the rest !

TheEagle
  • 5,808
  • 3
  • 11
  • 39
  • There is syntax error on the line `p = multiprocessing.Process(hello)`, it should be `p = multiprocessing.Process(target=hello)` instead. Also running `quitprog()` in other process cannot terminate current process. – acw1668 Nov 29 '21 at 08:13