Some system info before proceeding further:

Platform: Mac OS X 10.7.1
Python Version: ActiveState Python 2.7.1
wxPython Version: wxPython2.9-osx-cocoa-py2.7

I want the button label to be changed while performing a task

So, here is what I did/want:

self.run_button=wx.Button(self.panel,ID_RUN_BUTTON,label='Install')
self.Bind(wx.EVT_BUTTON, self.OnRun,id=ID_RUN_BUTTON)

def OnRun(self,evt):
	self.run_button.SetLabel('Installing..')
	#call a function that does the installation task
	installation_task()
	#After task completion, set the button label back to "Install"
	self.run_button.SetLabel('Install')

When I try doing this, it doesn't set the label to "Installing" while the task is being performed. Any suggestions how do I achieve this?

Dani AI

Generated

This is a classic GUI-thread issue. As noted, a very fast task will hide the label change — but more commonly the label doesn't repaint because the main (GUI) thread is blocked by the installation work. SetLabel schedules a repaint but that won't be processed until the event loop runs again. The robust fix is to run the long task in a background thread and marshal UI updates back onto the main thread.

A safe pattern (compatible with wxPython on Python 2.7) is: set the button state, start a worker thread, run the install in the thread, and use wx.CallAfter to restore the UI when the worker finishes. Disable the button while the job runs to avoid re-entrancy.

import threading
import wx

def OnRun(self, evt):
    self.run_button.Disable()
    self.run_button.SetLabel("Installing...")
    self.run_button.Refresh()
    t = threading.Thread(target=self._install_worker)
    t.setDaemon(True)
    t.start()

def _install_worker(self):
    try:
        installation_task()   # long-running work
    finally:
        wx.CallAfter(self._install_done)

def _install_done(self):
    self.run_button.SetLabel("Install")
    self.run_button.Enable()

Quick alternatives and cautions: forcing an immediate repaint with Refresh() plus wx.Yield() can make the label appear, but wx.Yield() introduces re-entrancy risks and is only a short-term hack. Do not call GUI methods from a non-main thread — always use wx.CallAfter, wx.PostEvent or pubsub to update controls. For user feedback on long operations consider wx.BusyInfo, wx.BusyCursor, or a wx.ProgressDialog so users see progress rather than a frozen button.

Hi.
If installation_task() is a function that terminates fast, you will probably not see the label change, because it's very fast.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.