-1

Please help me with this.

My situation is that I have a tkinter GUI. When I click a button on the GUI, it invokes a function A implemented in the GUI and runs another function B in another package. Now, since function B implements time.sleep() for 15 mins if some condition is met, I'm wondering if there is a way that I can output a message in the GUI window when function B is paused so that the user of the GUI knows that the program is not down.

Here is a simplified example. GUI is defined in a class:

from tkinter import *
from pk1 import funcB

class scrapApp(Tk):
    def __init__(self):
        super().__init__()
    def funcA(self):
        funcB(self)
    def funcC():
        print("dddddd")

if __name__ == "__main__":
    app = scrapApp()
    app.mainloop()

funcB in pk1

def funcB(a):
    if ("something happens" == True):
        a.funcC()
        time.sleep(15*60)

Please advise. Thanks a lot.

joeW
  • 13
  • 3
  • I think it is possible if you put the function in a new thread. I use Qt, not tkinter. a signal need to be sent before the function b is set to pause. You can do that in qt with a pyqtsignal and the main thread will catch the signal to display a message box. I think it could have an equivalent in tkinter. – ymmx Jun 01 '22 at 06:52
  • If you put a minimal example we could working on it – ymmx Jun 01 '22 at 06:52
  • I don't think the main process needs to detect the function state at all, just let the thread executing the function create a popover before sleep You can create a pop-box by `tkinter.Toplevel()` If you want, you can even build a progress bar by `ttk.Progressbar()` to remind the user how long the wait is over. – CN-LanBao Jun 01 '22 at 07:34
  • @CN-LanBao thanks for your comment. But I didn't quite get it yet. The challenge for me is that function B that has sleep() implemented is in another package and has nothing to do with GUI. So, how could function B signal function A in GUI that it is in pause mode? Or how does function A in GUI know the program is in pause and show the pop-box you mentioned? Please advise. thanks ! – joeW Jun 01 '22 at 07:46
  • @joeW In the absence of practical examples, I make the following assumptions,You create a thread to call `B()`. You can take your `tkinter.Tk` as an argument to `B()`, and modify the `B()` to create a pop-box. There is no need for `A()` to monitor `B()` state. However, if you dont want to modify `B()`, you can reference @ymmx 's advice to fix by SIGNAL, but i think it will be complex – CN-LanBao Jun 01 '22 at 07:56
  • @joeW You can also write the code that generates the popover in a function and take B to call it – CN-LanBao Jun 01 '22 at 07:58
  • @CN-LanBao thanks for your response. I have added an example in the question as suggested. I think I get what you meant and will see if I can modify B(). – joeW Jun 01 '22 at 08:09
  • @ymmx thank you. I have added an example as suggested. Singaling sounds a bit complex as I don't seem to find something similar in Tkinter. – joeW Jun 01 '22 at 08:11
  • @joeW Yeah, you can `def funcC(self)` in Class `scrapApp` contains `pop_box = pop_box = tkinter.Toplevel(self)` and `pop_box .transient(self)`. Call `C()` from `B()` – CN-LanBao Jun 01 '22 at 09:24
  • @CN-LanBao thanks. that's very helpful. But how should I call funcC() in funcB? I mean since C(self) is a method of class scrapApp and B() is in another python file, how am I supposed to let B() call a method of the exact object (app) defined? I'm just not sure what parameter should be passed to B() in pk1. Thanks! – joeW Jun 01 '22 at 09:42
  • @joeW For example, `funcB()` add param `funcB(test)` and call `C()` in B by `test.funcC()`. In `funcA`, change `funcB()` to `funcB(self)` – CN-LanBao Jun 01 '22 at 09:51
  • @joeW Like this `class scrapApp(Tk): def __init__(self): super().__init__() def funcA(self): funcB(self) def funcC(self): pop_box = tkinter.Toplevel(self) pop_box.transient(self) def funcB(a): a.funcC()` – CN-LanBao Jun 01 '22 at 09:52
  • @CN-LanBao thank you very much. I did the same thing. However, I got error saying "a is not defined". Please could you check what is wrong with my code? Do I need to import the file or class in pk1.py? I hope you can see it now. I don't know what stackoverfolow doesn't allow me to post the questions, though I have modified it again and agian. – joeW Jun 01 '22 at 10:14
  • @joeW Change `def funcC():` to `def funcC(self):`, and it works fine on my computer – CN-LanBao Jun 01 '22 at 10:23
  • Even your modification is structured more or less identical to [this answer](https://stackoverflow.com/a/53526742/) as linked in one of the above duplicate candidates, so perhaps please try that out first and then explain why the answer did not address your issue (and request the question to be reopened if that is the case). – metatoaster Jun 01 '22 at 10:23
  • @joeW You can add `threading.Thread(target=self.funcA).start()` in `__init__` to debug – CN-LanBao Jun 01 '22 at 10:26
  • @CN-LanBao Thanks a lot. It does work. I messed up with the variable names.. – joeW Jun 01 '22 at 11:14

0 Answers0