1

I've been fighting with Tkinter for a while now and have exhausted most the resources I have for referencing this. I've found a couple similar topics here but none quite bring me to where I need to be.

I've got a long running (not long actually, it only takes 10-12 secs) python script that silently install an application using subprocess from the CLI. Subprocess worked and it successfully installed the application, however, the GUI locks (i.e hangs/freeze) after the execution (and the program no longer run the succeeding code). I know I have to use threading here but I've already tried using it to no avail.

As part of my learning process, I cloned a repo from Github and modify it to run on Windows (since it only run in MAC platform) and planning to extend it, and this is the part where I got stucked. This is my first time to use TKinter and I apologize if I have missed something stupid or not asked the question in the right way. Hope you can help me and thank you in advance for the assistance.

Code can be found on this link.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
Maynard
  • 25
  • 4

2 Answers2

0

You have defined a button

installButton = Button(bottomFrame, text=installButtonTxt,
                       command=on_install_thread, width=9)

with command handler

def on_install_thread():
    ...
    loop_thread = threading.Thread(target=on_install_button_active,
                                   args=['button', 'model', itemSelectCount])

and the target for thread on_install_button_active.

Then

def on_install_button_active(button, model, selectcount):
    ...
    # Reset install status
    installStatus = 'complete'
    # Remove Cancel Button
    cancelButton.destroy()
    # Activate Install/Done button and menus
    installButton.configure(state=NORMAL)
    # menuControl('normal')
    refreshGui(mainWindow)

It looks like there is code at the end of on_install_button_active that involves Tkinter widgets. Calling tkinter methods from other threads seems to be unreliable, for example 1.

It is possible to define virtual events

def renderMainWindow():
    ...
    mainWindow.bind('<<InstallComplete>>', on_install_complete)

def on_install_complete():
    cancelButton.destroy()
    installButton.configure(state=NORMAL)

def on_install_button_active(button, model, selectcount):
    ...
    # Reset install status
    installStatus = 'complete'

    mainWindow.event_generate('<<InstallComplete>>', when='tail')

If there are other calls in that thread that involve Tkinter widgets, it might be better to remove them.

J.J. Hakala
  • 6,136
  • 6
  • 27
  • 61
  • Hello J.J., thanks, I will try this approach when I got home. One thing though, the code I provided was working from MAC platform, but this is still worth a try. How about the subprocess function? It takes 10-15 seconds to execute (albeit it worked correctly), do you think it has something to do that leads the GUI to froze? – Maynard Jul 16 '16 at 11:35
  • Hello again J.J. thanks very much for this, I was able to successfully update the cancel and install button using this approach and GUI does not hang. I just added an event parameter to on_install_complete(event) since I was getting an error. I also removed other calls that involve Tkinter widgets and made a separate virtual events for them but somehow its not working (i.e. GUI freezes). Here are the [codes](http://pastebin.com/u28UqLHg) that I added. I can't seem to get a workaround on this, hoping for your assistance again and thank in advance. – Maynard Jul 18 '16 at 07:33
  • @Maynard it is quite hard to guess what could be wrong without seeing the complete code – J.J. Hakala Jul 20 '16 at 21:10
  • Hello J.J., regret for not showing the whole code, please see it [here](http://pastebin.com/u28UqLHg), thanks again for the help. – Maynard Jul 22 '16 at 09:25
0

I was able to resolved problems with my GUI by using mtTkinter and by referring to this post.

Community
  • 1
  • 1
Maynard
  • 25
  • 4