Page 1 of 1

Thread-safe GUI updates

Posted: Thu Apr 14, 2005 10:40 pm
by DaWanderer
Hello, everyone. I've been searching for a days now on how to update my GUI from a separate thread. I've found that Utils.MutexGuiEnter and Utils.MutexGuiLeave do not work.

The other suggested solution was to post a custom event to the main window and handle it in the main thread. Does anyone have an example of how to do this? I assume that I'd need to derive a class from Event, but an IntPtr parameter is required to create a new Event object. I'm looking for a fully managed way to do this if possible.

Posted: Fri Apr 15, 2005 3:29 pm
by nummish
requires building the CVS head, as the patches for this are fairly new

Code: Select all

using wx;

using System;

public class EventTest : Frame
	public EventTest() : base("EventTest", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE)

	private TextCtrl txtResults;

	private Button butEvent1;
	private Button butEvent2;
	private Button butCombinedEvents;

	public void InitializeComponent()
		BoxSizer sizMain = new BoxSizer(Orientation.wxVERTICAL);

		txtResults = new TextCtrl(this, "");
		butEvent1 = new Button(this, "Event One");
		butEvent2 = new Button(this, "Event Two");
		butCombinedEvents = new Button(this, "Both Events");
		sizMain.Add(txtResults, 0, Stretch.wxEXPAND, 0);
		sizMain.Add(butEvent1, 0, 0, 0);
		sizMain.Add(butEvent2, 0, 0, 0);
		sizMain.Add(butCombinedEvents, 0, 0, 0);


		EVT_BUTTON(butEvent1.ID, new EventListener(OnButton1_Click));
		EVT_BUTTON(butEvent2.ID, new EventListener(OnButton2_Click));
		EVT_BUTTON(butCombinedEvents.ID, new EventListener(OnCombinedButton_Click));

		_Update1 = Window.UniqueID;
		_Update2 = Window.UniqueID;

		EVT_UPDATE_UI(_Update1, new EventListener(OnButton1_Click));
		EVT_UPDATE_UI(_Update2, new EventListener(OnButton2_Click));

	private int _Update1;
	private int _Update2;

	private void OnButton1_Click(object sender, Event evt)
		txtResults.Value += " one ";
	private void OnButton2_Click(object sender, Event evt)
		txtResults.Value += " two ";

	private void OnCombinedButton_Click(object sender, Event evt)
				EventHandler.AddPendingEvent(new UpdateUIEvent(_Update2));
				EventHandler.AddPendingEvent(new UpdateUIEvent(_Update1));


public class EventTestApp : App
	public static void Main(string[] args)
		EventTestApp eva = new EventTestApp();
	public override bool OnInit()
		EventTest ev = new EventTest();
		return true;

Posted: Fri Apr 15, 2005 4:41 pm
by DaWanderer
Thank you, nummish. This has saved me a lot of trouble.

Posted: Tue Mar 07, 2006 7:13 pm
by billglover
Despite following the discussion so far I am still having problems.

From the examples given I have done the following:

In my fame class:

Code: Select all

_Update1 = Window.UniqueID;
EVT_UPDATE_UI(_Update1, new EventListener(OnDoSomethingElse));

In the thread:

Code: Select all

parent.AddPendingEvent(new wx.UpdateUIEvent(update));

This works as expected and I can trigger the OnDoSomethingElse event from within the thread. However I want to pass data from the thread back to the main GUI. Specifically I am looking to update a progress bar. I would have thought that I could create a custom wx.Event and use this to pass the data in the EventArgs.

Firstly, is this the right way to go about doing what I'm trying to do?

Secondly, how would I go about creating a custom wx.Event?

Any help would be much appreciated as this has proved a real headache up until now.

Thanks in advance.