-1

I have only one while loop and the Tkonter say: GUI is not responding. What I'm doing wrong ? I would like with button "Pause" break and again with "button "Start" continue the program.

import Tkinter, time

root = Tkinter.Tk
class InterfaceApp(root):
    def __init__ (self, parent):
        root.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):
        self.but_state = 0

        self.but_start = Tkinter.Button(self, text='Start', command=lambda: self.Start(), width=10)
        self.but_pause = Tkinter.Button(self, text="Pause", command=lambda: self.Pause(), width=10)
        self.but_stop = Tkinter.Button(self, text='Stop', command=lambda: self.Stop(), width=10)
        self.but_start.grid(row=1, column=1, sticky='W')
        self.but_pause.grid(row=1, column=2, sticky='W')
        self.but_stop.grid(row=1, column=3, sticky='W')

    def Start(self):

        while True:
            print "X"
            time.sleep(2)
            if self.but_state == 1:
                break
            else:
                continue

    def Stop(self):
        self.but_state = 1

    def Pause(self):
        pass


if __name__ == "__main__":
    app = InterfaceApp(None)
    app.title("MPW4 microHP - Long Term Test")
    app.mainloop()
Mirza Grbic
  • 152
  • 1
  • 3
  • 14
  • I guess the `while` loop blocks any incoming event from the other buttons, so you never have the opportunity to set `self.but_state` to 1. You can try using the [threading](https://docs.python.org/2/library/threading.html) module. – Frodon Jul 20 '16 at 10:07
  • 1
    Well, it's not a good idea to use infinite loop (`while True:`) inside Tkinter at all. It will stop responding of course. – Parviz Karimli Jul 20 '16 at 10:15
  • But before the infinite loop, the problem is @MirzaGrbic has put the program body (buttons) in a wrong place (inside `initialize`) -- it has to be inside the constructor (`__init__`) instead. Another problem is lamdba functions have not been defined properly. – Parviz Karimli Jul 20 '16 at 10:37
  • @ParvizKarimli it's ok since `initialize` is called from `__init__` – Frodon Jul 20 '16 at 11:57
  • @Frodon that's right, I just noticed `self.initialize()` inside `__init__`. – Parviz Karimli Jul 20 '16 at 12:08

2 Answers2

3

First issue:

Using the while loop. To call a function again after it finished use

self.after(<time in ms>, <function to call>)

at the end of your def Start(self)

Would look like this:


# ...
def Start(self):
    print("X")
    if self.but_state == 0:
        self.after(2000, self.Start)
# ...

Second Issue:

Do not use lambdas for simple calls. Use the name for the binding instead, just like @Parviz_Karimli pointed out.

def initialize(self):
    self.but_state = 0

    self.but_start = Tkinter.Button(self, text='Start', command=self.Start, width=10)
    self.but_pause = Tkinter.Button(self, text="Pause", command=self.Pause, width=10)
    self.but_stop = Tkinter.Button(self, text='Stop', command=self.Stop, width=10)
    self.but_start.grid(row=1, column=1, sticky='W')
    self.but_pause.grid(row=1, column=2, sticky='W')
    self.but_stop.grid(row=1, column=3, sticky='W')
R4PH43L
  • 2,122
  • 3
  • 18
  • 30
1

Your code is nonsense. You have to figure out how to define functions and use them properly first. I wrote a little example for you:

from tkinter import *

class App:
    def __init__(self, master):
        self.master = master

        self.startb = Button(master, text="Start", command=self.startf)
        self.startb.pack()

        self.pauseb = Button(master, text="Pause", command=self.pausef)
        self.pauseb.pack()

        self.stopb = Button(master, text="Stop", command=self.stopf)
        self.stopb.pack()

    def startf(self):
        print("Started")
        self.after_id = self.master.after(1000, self.startf)

    def pausef(self):
        if self.startf is not None: # to handle any exception
            self.master.after_cancel(self.after_id) # this will pause startf function -- you can start again
            print("Paused")

    def stopf(self):
        if self.startf is not None:
            self.master.after_cancel(self.after_id)
            self.startf = None # this will stop startf function -- you cannot start again
            print("Stopped")



root = Tk()
myapp = App(root)
root.mainloop()

Then you can modify this code -- change the behaviors of the functions etc. If you have a working piece of code which will behave as the "motor" function that does the core idea of your program, include that function in as well, and return it in the startf function, pause it in the pausef function, and finally, stop it in the stopf function.
P.S.: My code was written in Python 3.
EDIT: I completed the code and above is a working program that starts, pauses and stops depending on the button you click.

Parviz Karimli
  • 1,247
  • 1
  • 14
  • 26