Trying to fix tkinter GUI freeze-ups (using threads)

前端 未结 3 529
谎友^
谎友^ 2020-12-04 02:57

I have a Python 3.x report creator that is so I/O bound (due to SQL, not python) that the main window will \"lock up\" for minutes while the reports are being creat

3条回答
  •  日久生厌
    2020-12-04 03:34

    I've modified the question to include the accidentally omitted but critical line. The answer to avoiding GUI freezeups turns out to be embarrassingly simple:

    Don't call ".join()" after launching the thread.
    

    In addition to the above, a complete solution involves:

    • Disabling the "Do Reports" button until the "create report" thread finishes (technically not necessary but preventing extra report creation threads also prevents user confusion);
    • Having the "create report" thread update the main thread using these events:
      • "Completed report X" (an enhancement that displays progress on GUI), and
      • "Completed all reports" (display the "Done" window and reenable the "Do Reports" button);
    • Moving the invocation of the "Done" window to the main thread, invoked by the above event; and
    • Passing data with the event instead of using shared global variables.

    A simple approach using the multiprocessing.dummy module (available since 3.0 and 2.6) is:

        from multiprocessing.dummy import Process
    
        ReportCreationProcess = Process( target = DoChosenReports )
        ReportCreationProcess.start()
    

    again, note the absence of a .join() line.

    As a temporary hack the "Done" window is still being created by the create report thread just before it exits. That works but does cause this runtime error:

    RuntimeError: Calling Tcl from different appartment  
    

    however the error doesn't seem to cause problems. And, as other questions have pointed out, the error can be eliminated by moving the creation of the "DONE" window into the main thread (and have the create reports thread send an event to "kick off" that window).

    Finally my thanks to @TigerhawkT3 (who posted a good overview of the approach I'm taking) and @martineau who covered how to handle the more general case and included a reference to what looks like a useful resource. Both answers are worth reading.

提交回复
热议问题