0

I am working on a program that has a main GUI. From here the user inputs their information and clicks "go." When this happens the GUI calls a function from another file, which takes a few hours to run. The issue I am having is while this function is running the GUI will go blank and be unresponsive (as it should). I'm trying to find the best way of writing this so that the GUI stays responsive and can run other things. Additionally, if possible I would like main GUI to display the progress of the wrapper function.

I can't find a way to do this so that the main GUI knows when the function has finished running. This is important because the "run" button is turned off so that it is not accidentally run multiple times, but needs to be turned back on when everything is complete. Additionally, all of the solutions I have read about involve me converting the functions.py file to a giant class. If there is a benefit to this then I am fine doing this, but I do not see any large advantage to this and thus intended to keep is as functions.

As for what the MainWindow is doing while this function is running: it will need to take input in and open an additional ResultsWindow.

Here is what my file structure looks like:

  • ui_MainWindow.py - from Qt Designer

  • Main.py - runs the ui_MainWindow and calls all functions

  • functions.py - contains many functions as well as two "wrapper functions." These wrapper functions are the ones that take a while to run, but there are other functions in here that are called by themselves.

  • Results.py - this is another GUI that is coded (not made in Qt Designer) that I should be able to be call at any time.

This is what Main.py looks like:

import functions
import ui_Main.py

class MainWindow(...):
    def __init__(self, parent=None):
        self.btn.clicked.connect(self.run)
        self.btn2.clicked.connect(self.OpenResults)
    def run(self):
        finished_status = functions.wrapper1(arguments)
        self.statusbar.showMessage(finished_status)
    def OpenResults(self):
        if self.resultsWindow != None:
            self.resultsWindow.close()
        self.resultsWindow = LiveData.main(arguments)
        self.resultsWindow.show()

Here is what functions.py looks like:

def func1(args):
    do some stuff
def func2(args):
    do some stuff
def func3(args):
    do some stuff
def wrapper(many args):
    for i in range(0,arg1):
        func1(args)
        func2(args)
        ...
def wrapper(many args):
    for i in range(0, arg1):
        func1(args)
        func3(args)
        ...
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • There are dozens of SO answers that can easily be adapted to solve your problem. You need a small `QObject` class for the signals, but apart from that your functions can probably stay much are they are. The only proviso is that the long running function needs a mechanism (e.g. a simple callback) to report its current progress to the worker thread. Then the worker thread can send a signal back the main thread to update the gui. The [answer here](http://stackoverflow.com/a/39999236/984421) has a working example with most of the structure. Any reason why I shouldn't close your question as a dup? – ekhumoro Dec 21 '16 at 19:16
  • Maybe I asked the question incorrectly, but I was wondering if this were possible without creating a class. I do not understand the need for it. Perhaps something like "thread.start_new_thread(someFunc, ())" however, I was hoping to find something similar that was able to read values back from the function. – Dillon Martin Dec 21 '16 at 19:39
  • Your example code already creates a class (`MainWindow`). I already explained why the `QObject` class is needed (signals). I really don't see how calling the functions from your `MainWindow` class is any different from calling them from a worker class. – ekhumoro Dec 21 '16 at 19:47

0 Answers0