Added wxWakeUpMainThread, wxMutexGuiEnter, wxMutexGuiLeave,

wxMutexGuiLocker and wxThread_IsMain to assist with dealing with GUI
access from non-GUI threads.

wxPyOnDemandOutputWindow is now thread safe if non-GUI threads use
print, sys.stdout.write, etc.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@9590 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2001-03-26 22:17:24 +00:00
parent c1e820a40e
commit 6e18ca6cf4
8 changed files with 297 additions and 49 deletions

View File

@@ -17,6 +17,13 @@ Also wxTheColourDatabase and added a library module (in the
wxPython.lib.colourdb module) to load LOTS more colour names into the wxPython.lib.colourdb module) to load LOTS more colour names into the
colour database. colour database.
Added wxWakeUpMainThread, wxMutexGuiEnter, wxMutexGuiLeave,
wxMutexGuiLocker and wxThread_IsMain to assist with dealing with GUI
access from non-GUI threads.
wxPyOnDemandOutputWindow is now thread safe if non-GUI threads use
print, sys.stdout.write, etc.

View File

@@ -714,20 +714,22 @@ class wxPyOnDemandOutputWindow:
self.title = title self.title = title
self.parent = None self.parent = None
def SetParent(self, parent): def SetParent(self, parent):
self.parent = parent self.parent = parent
def OnCloseWindow(self, event): def OnCloseWindow(self, event):
if self.frame != None: if self.frame != None:
self.frame.Destroy() self.frame.Destroy()
self.frame = None self.frame = None
self.text = None self.text = None
# These methods provide the file-like output behaviour.
# this provides the file-like output behaviour
def write(self, str): def write(self, str):
if not wxThread_IsMain():
# Aquire the GUI mutex before making GUI calls. Mutex is released
# when locker is deleted a the end of this function.
locker = wxMutexGuiLocker()
if not self.frame: if not self.frame:
self.frame = wxFrame(self.parent, -1, self.title) self.frame = wxFrame(self.parent, -1, self.title)
self.text = wxTextCtrl(self.frame, -1, "", self.text = wxTextCtrl(self.frame, -1, "",
@@ -737,13 +739,13 @@ class wxPyOnDemandOutputWindow:
EVT_CLOSE(self.frame, self.OnCloseWindow) EVT_CLOSE(self.frame, self.OnCloseWindow)
self.text.AppendText(str) self.text.AppendText(str)
def close(self): def close(self):
if self.frame != None: if self.frame != None:
if not wxThread_IsMain():
locker = wxMutexGuiLocker()
self.frame.Close() self.frame.Close()
_defRedirect = (wxPlatform == '__WXMSW__') _defRedirect = (wxPlatform == '__WXMSW__')
#---------------------------------------------------------------------- #----------------------------------------------------------------------

View File

@@ -382,10 +382,28 @@ public:
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool wxSafeYield(wxWindow* win=NULL);
void wxPostEvent(wxEvtHandler *dest, wxEvent& event); void wxPostEvent(wxEvtHandler *dest, wxEvent& event);
void wxWakeUpIdle(); void wxWakeUpIdle();
bool wxSafeYield(wxWindow* win=NULL);
void wxWakeUpMainThread();
void wxMutexGuiEnter();
void wxMutexGuiLeave();
class wxMutexGuiLocker {
public:
wxMutexGuiLocker();
~wxMutexGuiLocker();
};
%inline %{
bool wxThread_IsMain() {
return wxThread::IsMain();
}
%}
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

@@ -66,12 +66,12 @@ extern PyObject *SWIG_newvarlink(void);
static PyObject* l_output_helper(PyObject* target, PyObject* o) { static PyObject* l_output_helper(PyObject* target, PyObject* o) {
PyObject* o2; PyObject* o2;
if (!target) { if (!target) {
target = o; target = o;
} else if (target == Py_None) { } else if (target == Py_None) {
Py_DECREF(Py_None); Py_DECREF(Py_None);
target = o; target = o;
} else { } else {
if (!PyList_Check(target)) { if (!PyList_Check(target)) {
o2 = target; o2 = target;
target = PyList_New(0); target = PyList_New(0);
@@ -88,23 +88,23 @@ static PyObject* t_output_helper(PyObject* target, PyObject* o) {
PyObject* o2; PyObject* o2;
PyObject* o3; PyObject* o3;
if (!target) { if (!target) {
target = o; target = o;
} else if (target == Py_None) { } else if (target == Py_None) {
Py_DECREF(Py_None); Py_DECREF(Py_None);
target = o; target = o;
} else { } else {
if (!PyTuple_Check(target)) { if (!PyTuple_Check(target)) {
o2 = target; o2 = target;
target = PyTuple_New(1); target = PyTuple_New(1);
PyTuple_SetItem(target, 0, o2); PyTuple_SetItem(target, 0, o2);
} }
o3 = PyTuple_New(1); o3 = PyTuple_New(1);
PyTuple_SetItem(o3, 0, o); PyTuple_SetItem(o3, 0, o);
o2 = target; o2 = target;
target = PySequence_Concat(o2, o3); target = PySequence_Concat(o2, o3);
Py_DECREF(o2); Py_DECREF(o2);
Py_DECREF(o3); Py_DECREF(o3);
} }
return target; return target;
@@ -158,6 +158,10 @@ IMP_PYCALLBACK_BOOL_STRING(wxPyFontEnumerator, wxFontEnumerator, OnFacename);
IMP_PYCALLBACK_BOOL_STRINGSTRING(wxPyFontEnumerator, wxFontEnumerator, OnFontEncoding); IMP_PYCALLBACK_BOOL_STRINGSTRING(wxPyFontEnumerator, wxFontEnumerator, OnFontEncoding);
bool wxThread_IsMain() {
return wxThread::IsMain();
}
class wxPyTipProvider : public wxTipProvider { class wxPyTipProvider : public wxTipProvider {
public: public:
wxPyTipProvider(size_t currentTip) wxPyTipProvider(size_t currentTip)
@@ -1547,6 +1551,32 @@ static PyObject *_wrap_wxCaret_SetBlinkTime(PyObject *self, PyObject *args, PyOb
return _resultobj; return _resultobj;
} }
static PyObject *_wrap_wxSafeYield(PyObject *self, PyObject *args, PyObject *kwargs) {
PyObject * _resultobj;
bool _result;
wxWindow * _arg0 = (wxWindow *) NULL;
PyObject * _argo0 = 0;
char *_kwnames[] = { "win", NULL };
self = self;
if(!PyArg_ParseTupleAndKeywords(args,kwargs,"|O:wxSafeYield",_kwnames,&_argo0))
return NULL;
if (_argo0) {
if (_argo0 == Py_None) { _arg0 = NULL; }
else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxWindow_p")) {
PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxSafeYield. Expected _wxWindow_p.");
return NULL;
}
}
{
wxPy_BEGIN_ALLOW_THREADS;
_result = (bool )wxSafeYield(_arg0);
wxPy_END_ALLOW_THREADS;
} _resultobj = Py_BuildValue("i",_result);
return _resultobj;
}
static PyObject *_wrap_wxPostEvent(PyObject *self, PyObject *args, PyObject *kwargs) { static PyObject *_wrap_wxPostEvent(PyObject *self, PyObject *args, PyObject *kwargs) {
PyObject * _resultobj; PyObject * _resultobj;
wxEvtHandler * _arg0; wxEvtHandler * _arg0;
@@ -1599,26 +1629,68 @@ static PyObject *_wrap_wxWakeUpIdle(PyObject *self, PyObject *args, PyObject *kw
return _resultobj; return _resultobj;
} }
static PyObject *_wrap_wxSafeYield(PyObject *self, PyObject *args, PyObject *kwargs) { static PyObject *_wrap_wxWakeUpMainThread(PyObject *self, PyObject *args, PyObject *kwargs) {
PyObject * _resultobj; PyObject * _resultobj;
bool _result; char *_kwnames[] = { NULL };
wxWindow * _arg0 = (wxWindow *) NULL;
PyObject * _argo0 = 0;
char *_kwnames[] = { "win", NULL };
self = self; self = self;
if(!PyArg_ParseTupleAndKeywords(args,kwargs,"|O:wxSafeYield",_kwnames,&_argo0)) if(!PyArg_ParseTupleAndKeywords(args,kwargs,":wxWakeUpMainThread",_kwnames))
return NULL; return NULL;
if (_argo0) {
if (_argo0 == Py_None) { _arg0 = NULL; }
else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxWindow_p")) {
PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxSafeYield. Expected _wxWindow_p.");
return NULL;
}
}
{ {
wxPy_BEGIN_ALLOW_THREADS; wxPy_BEGIN_ALLOW_THREADS;
_result = (bool )wxSafeYield(_arg0); wxWakeUpMainThread();
wxPy_END_ALLOW_THREADS;
} Py_INCREF(Py_None);
_resultobj = Py_None;
return _resultobj;
}
static PyObject *_wrap_wxMutexGuiEnter(PyObject *self, PyObject *args, PyObject *kwargs) {
PyObject * _resultobj;
char *_kwnames[] = { NULL };
self = self;
if(!PyArg_ParseTupleAndKeywords(args,kwargs,":wxMutexGuiEnter",_kwnames))
return NULL;
{
wxPy_BEGIN_ALLOW_THREADS;
wxMutexGuiEnter();
wxPy_END_ALLOW_THREADS;
} Py_INCREF(Py_None);
_resultobj = Py_None;
return _resultobj;
}
static PyObject *_wrap_wxMutexGuiLeave(PyObject *self, PyObject *args, PyObject *kwargs) {
PyObject * _resultobj;
char *_kwnames[] = { NULL };
self = self;
if(!PyArg_ParseTupleAndKeywords(args,kwargs,":wxMutexGuiLeave",_kwnames))
return NULL;
{
wxPy_BEGIN_ALLOW_THREADS;
wxMutexGuiLeave();
wxPy_END_ALLOW_THREADS;
} Py_INCREF(Py_None);
_resultobj = Py_None;
return _resultobj;
}
static PyObject *_wrap_wxThread_IsMain(PyObject *self, PyObject *args, PyObject *kwargs) {
PyObject * _resultobj;
bool _result;
char *_kwnames[] = { NULL };
self = self;
if(!PyArg_ParseTupleAndKeywords(args,kwargs,":wxThread_IsMain",_kwnames))
return NULL;
{
wxPy_BEGIN_ALLOW_THREADS;
_result = (bool )wxThread_IsMain();
wxPy_END_ALLOW_THREADS; wxPy_END_ALLOW_THREADS;
} _resultobj = Py_BuildValue("i",_result); } _resultobj = Py_BuildValue("i",_result);
@@ -3160,6 +3232,58 @@ static PyObject *_wrap_delete_wxWindowDisabler(PyObject *self, PyObject *args, P
return _resultobj; return _resultobj;
} }
#define new_wxMutexGuiLocker() (new wxMutexGuiLocker())
static PyObject *_wrap_new_wxMutexGuiLocker(PyObject *self, PyObject *args, PyObject *kwargs) {
PyObject * _resultobj;
wxMutexGuiLocker * _result;
char *_kwnames[] = { NULL };
char _ptemp[128];
self = self;
if(!PyArg_ParseTupleAndKeywords(args,kwargs,":new_wxMutexGuiLocker",_kwnames))
return NULL;
{
wxPy_BEGIN_ALLOW_THREADS;
_result = (wxMutexGuiLocker *)new_wxMutexGuiLocker();
wxPy_END_ALLOW_THREADS;
} if (_result) {
SWIG_MakePtr(_ptemp, (char *) _result,"_wxMutexGuiLocker_p");
_resultobj = Py_BuildValue("s",_ptemp);
} else {
Py_INCREF(Py_None);
_resultobj = Py_None;
}
return _resultobj;
}
#define delete_wxMutexGuiLocker(_swigobj) (delete _swigobj)
static PyObject *_wrap_delete_wxMutexGuiLocker(PyObject *self, PyObject *args, PyObject *kwargs) {
PyObject * _resultobj;
wxMutexGuiLocker * _arg0;
PyObject * _argo0 = 0;
char *_kwnames[] = { "self", NULL };
self = self;
if(!PyArg_ParseTupleAndKeywords(args,kwargs,"O:delete_wxMutexGuiLocker",_kwnames,&_argo0))
return NULL;
if (_argo0) {
if (_argo0 == Py_None) { _arg0 = NULL; }
else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxMutexGuiLocker_p")) {
PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of delete_wxMutexGuiLocker. Expected _wxMutexGuiLocker_p.");
return NULL;
}
}
{
wxPy_BEGIN_ALLOW_THREADS;
delete_wxMutexGuiLocker(_arg0);
wxPy_END_ALLOW_THREADS;
} Py_INCREF(Py_None);
_resultobj = Py_None;
return _resultobj;
}
#define delete_wxTipProvider(_swigobj) (delete _swigobj) #define delete_wxTipProvider(_swigobj) (delete _swigobj)
static PyObject *_wrap_delete_wxTipProvider(PyObject *self, PyObject *args, PyObject *kwargs) { static PyObject *_wrap_delete_wxTipProvider(PyObject *self, PyObject *args, PyObject *kwargs) {
PyObject * _resultobj; PyObject * _resultobj;
@@ -6616,6 +6740,8 @@ static PyMethodDef misc2cMethods[] = {
{ "wxTipProvider_GetCurrentTip", (PyCFunction) _wrap_wxTipProvider_GetCurrentTip, METH_VARARGS | METH_KEYWORDS }, { "wxTipProvider_GetCurrentTip", (PyCFunction) _wrap_wxTipProvider_GetCurrentTip, METH_VARARGS | METH_KEYWORDS },
{ "wxTipProvider_GetTip", (PyCFunction) _wrap_wxTipProvider_GetTip, METH_VARARGS | METH_KEYWORDS }, { "wxTipProvider_GetTip", (PyCFunction) _wrap_wxTipProvider_GetTip, METH_VARARGS | METH_KEYWORDS },
{ "delete_wxTipProvider", (PyCFunction) _wrap_delete_wxTipProvider, METH_VARARGS | METH_KEYWORDS }, { "delete_wxTipProvider", (PyCFunction) _wrap_delete_wxTipProvider, METH_VARARGS | METH_KEYWORDS },
{ "delete_wxMutexGuiLocker", (PyCFunction) _wrap_delete_wxMutexGuiLocker, METH_VARARGS | METH_KEYWORDS },
{ "new_wxMutexGuiLocker", (PyCFunction) _wrap_new_wxMutexGuiLocker, METH_VARARGS | METH_KEYWORDS },
{ "delete_wxWindowDisabler", (PyCFunction) _wrap_delete_wxWindowDisabler, METH_VARARGS | METH_KEYWORDS }, { "delete_wxWindowDisabler", (PyCFunction) _wrap_delete_wxWindowDisabler, METH_VARARGS | METH_KEYWORDS },
{ "new_wxWindowDisabler", (PyCFunction) _wrap_new_wxWindowDisabler, METH_VARARGS | METH_KEYWORDS }, { "new_wxWindowDisabler", (PyCFunction) _wrap_new_wxWindowDisabler, METH_VARARGS | METH_KEYWORDS },
{ "delete_wxBusyCursor", (PyCFunction) _wrap_delete_wxBusyCursor, METH_VARARGS | METH_KEYWORDS }, { "delete_wxBusyCursor", (PyCFunction) _wrap_delete_wxBusyCursor, METH_VARARGS | METH_KEYWORDS },
@@ -6664,9 +6790,13 @@ static PyMethodDef misc2cMethods[] = {
{ "wxDragIcon", (PyCFunction) _wrap_wxDragIcon, METH_VARARGS | METH_KEYWORDS }, { "wxDragIcon", (PyCFunction) _wrap_wxDragIcon, METH_VARARGS | METH_KEYWORDS },
{ "wxCreateFileTipProvider", (PyCFunction) _wrap_wxCreateFileTipProvider, METH_VARARGS | METH_KEYWORDS }, { "wxCreateFileTipProvider", (PyCFunction) _wrap_wxCreateFileTipProvider, METH_VARARGS | METH_KEYWORDS },
{ "wxShowTip", (PyCFunction) _wrap_wxShowTip, METH_VARARGS | METH_KEYWORDS }, { "wxShowTip", (PyCFunction) _wrap_wxShowTip, METH_VARARGS | METH_KEYWORDS },
{ "wxSafeYield", (PyCFunction) _wrap_wxSafeYield, METH_VARARGS | METH_KEYWORDS }, { "wxThread_IsMain", (PyCFunction) _wrap_wxThread_IsMain, METH_VARARGS | METH_KEYWORDS },
{ "wxMutexGuiLeave", (PyCFunction) _wrap_wxMutexGuiLeave, METH_VARARGS | METH_KEYWORDS },
{ "wxMutexGuiEnter", (PyCFunction) _wrap_wxMutexGuiEnter, METH_VARARGS | METH_KEYWORDS },
{ "wxWakeUpMainThread", (PyCFunction) _wrap_wxWakeUpMainThread, METH_VARARGS | METH_KEYWORDS },
{ "wxWakeUpIdle", (PyCFunction) _wrap_wxWakeUpIdle, METH_VARARGS | METH_KEYWORDS }, { "wxWakeUpIdle", (PyCFunction) _wrap_wxWakeUpIdle, METH_VARARGS | METH_KEYWORDS },
{ "wxPostEvent", (PyCFunction) _wrap_wxPostEvent, METH_VARARGS | METH_KEYWORDS }, { "wxPostEvent", (PyCFunction) _wrap_wxPostEvent, METH_VARARGS | METH_KEYWORDS },
{ "wxSafeYield", (PyCFunction) _wrap_wxSafeYield, METH_VARARGS | METH_KEYWORDS },
{ "wxCaret_SetBlinkTime", (PyCFunction) _wrap_wxCaret_SetBlinkTime, METH_VARARGS | METH_KEYWORDS }, { "wxCaret_SetBlinkTime", (PyCFunction) _wrap_wxCaret_SetBlinkTime, METH_VARARGS | METH_KEYWORDS },
{ "wxCaret_GetBlinkTime", (PyCFunction) _wrap_wxCaret_GetBlinkTime, METH_VARARGS | METH_KEYWORDS }, { "wxCaret_GetBlinkTime", (PyCFunction) _wrap_wxCaret_GetBlinkTime, METH_VARARGS | METH_KEYWORDS },
{ "wxToolTip_SetDelay", (PyCFunction) _wrap_wxToolTip_SetDelay, METH_VARARGS | METH_KEYWORDS }, { "wxToolTip_SetDelay", (PyCFunction) _wrap_wxToolTip_SetDelay, METH_VARARGS | METH_KEYWORDS },
@@ -6744,6 +6874,7 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
{ "_wxCursor","_class_wxCursor",0}, { "_wxCursor","_class_wxCursor",0},
{ "_wxNotifyEvent","_class_wxNotifyEvent",0}, { "_wxNotifyEvent","_class_wxNotifyEvent",0},
{ "_wxPyProcess","_class_wxPyProcess",0}, { "_wxPyProcess","_class_wxPyProcess",0},
{ "_wxMutexGuiLocker","_class_wxMutexGuiLocker",0},
{ "_wxLog","_class_wxLogWindow",SwigwxLogWindowTowxLog}, { "_wxLog","_class_wxLogWindow",SwigwxLogWindowTowxLog},
{ "_wxLog","_wxLogWindow",SwigwxLogWindowTowxLog}, { "_wxLog","_wxLogWindow",SwigwxLogWindowTowxLog},
{ "_wxLog","_class_wxLogGui",SwigwxLogGuiTowxLog}, { "_wxLog","_class_wxLogGui",SwigwxLogGuiTowxLog},
@@ -6760,6 +6891,7 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
{ "_byte","_unsigned_char",0}, { "_byte","_unsigned_char",0},
{ "_wxDataObject","_class_wxDataObject",0}, { "_wxDataObject","_class_wxDataObject",0},
{ "_class_wxPyFontEnumerator","_wxPyFontEnumerator",0}, { "_class_wxPyFontEnumerator","_wxPyFontEnumerator",0},
{ "_wxColourDatabase","_class_wxColourDatabase",0},
{ "_wxPyDataObjectSimple","_class_wxPyDataObjectSimple",0}, { "_wxPyDataObjectSimple","_class_wxPyDataObjectSimple",0},
{ "_wxPyDropSource","_class_wxPyDropSource",0}, { "_wxPyDropSource","_class_wxPyDropSource",0},
{ "_long","_unsigned_long",0}, { "_long","_unsigned_long",0},
@@ -6825,6 +6957,7 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
{ "_class_wxWindowDisabler","_wxWindowDisabler",0}, { "_class_wxWindowDisabler","_wxWindowDisabler",0},
{ "_char","_wxChar",0}, { "_char","_wxChar",0},
{ "_wxBitmap","_class_wxBitmap",0}, { "_wxBitmap","_class_wxBitmap",0},
{ "_wxPenList","_class_wxPenList",0},
{ "_wxWindowDC","_class_wxWindowDC",0}, { "_wxWindowDC","_class_wxWindowDC",0},
{ "_wxTimerEvent","_class_wxTimerEvent",0}, { "_wxTimerEvent","_class_wxTimerEvent",0},
{ "_wxPyTimer","_class_wxPyTimer",0}, { "_wxPyTimer","_class_wxPyTimer",0},
@@ -6832,9 +6965,11 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
{ "_class_wxNotifyEvent","_wxNotifyEvent",0}, { "_class_wxNotifyEvent","_wxNotifyEvent",0},
{ "_class_wxValidator","_wxValidator",0}, { "_class_wxValidator","_wxValidator",0},
{ "_class_wxPyEvent","_wxPyEvent",0}, { "_class_wxPyEvent","_wxPyEvent",0},
{ "_class_wxMutexGuiLocker","_wxMutexGuiLocker",0},
{ "_class_wxIconizeEvent","_wxIconizeEvent",0}, { "_class_wxIconizeEvent","_wxIconizeEvent",0},
{ "_class_wxBusyCursor","_wxBusyCursor",0}, { "_class_wxBusyCursor","_wxBusyCursor",0},
{ "_wxDropTarget","_class_wxDropTarget",0}, { "_wxDropTarget","_class_wxDropTarget",0},
{ "_class_wxColourDatabase","_wxColourDatabase",0},
{ "_wxScrollEvent","_class_wxScrollEvent",0}, { "_wxScrollEvent","_class_wxScrollEvent",0},
{ "_EBool","_wxCoord",0}, { "_EBool","_wxCoord",0},
{ "_EBool","_wxPrintQuality",0}, { "_EBool","_wxPrintQuality",0},
@@ -6854,8 +6989,10 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
{ "_class_wxDC","_wxDC",0}, { "_class_wxDC","_wxDC",0},
{ "_wxScrollWinEvent","_class_wxScrollWinEvent",0}, { "_wxScrollWinEvent","_class_wxScrollWinEvent",0},
{ "_wxGenericDragImage","_class_wxGenericDragImage",0}, { "_wxGenericDragImage","_class_wxGenericDragImage",0},
{ "_class_wxBrushList","_wxBrushList",0},
{ "_wxQueryNewPaletteEvent","_class_wxQueryNewPaletteEvent",0}, { "_wxQueryNewPaletteEvent","_class_wxQueryNewPaletteEvent",0},
{ "_wxPyInputStream","_class_wxPyInputStream",0}, { "_wxPyInputStream","_class_wxPyInputStream",0},
{ "_class_wxPenList","_wxPenList",0},
{ "_class_wxWindowCreateEvent","_wxWindowCreateEvent",0}, { "_class_wxWindowCreateEvent","_wxWindowCreateEvent",0},
{ "_class_wxOutputStream","_wxOutputStream",0}, { "_class_wxOutputStream","_wxOutputStream",0},
{ "_wxLogTextCtrl","_class_wxLogTextCtrl",0}, { "_wxLogTextCtrl","_class_wxLogTextCtrl",0},
@@ -6894,6 +7031,7 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
{ "_class_wxPyValidator","_wxPyValidator",0}, { "_class_wxPyValidator","_wxPyValidator",0},
{ "_class_wxCloseEvent","_wxCloseEvent",0}, { "_class_wxCloseEvent","_wxCloseEvent",0},
{ "_wxBusyInfo","_class_wxBusyInfo",0}, { "_wxBusyInfo","_class_wxBusyInfo",0},
{ "_wxFontList","_class_wxFontList",0},
{ "_class_wxMenuEvent","_wxMenuEvent",0}, { "_class_wxMenuEvent","_wxMenuEvent",0},
{ "_wxPaletteChangedEvent","_class_wxPaletteChangedEvent",0}, { "_wxPaletteChangedEvent","_class_wxPaletteChangedEvent",0},
{ "_wxJoystick","_class_wxJoystick",0}, { "_wxJoystick","_class_wxJoystick",0},
@@ -7020,10 +7158,12 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
{ "_wxPyDropTarget","_class_wxPyDropTarget",0}, { "_wxPyDropTarget","_class_wxPyDropTarget",0},
{ "_wxActivateEvent","_class_wxActivateEvent",0}, { "_wxActivateEvent","_class_wxActivateEvent",0},
{ "_class_wxBusyInfo","_wxBusyInfo",0}, { "_class_wxBusyInfo","_wxBusyInfo",0},
{ "_class_wxFontList","_wxFontList",0},
{ "_class_wxJoystick","_wxJoystick",0}, { "_class_wxJoystick","_wxJoystick",0},
{ "_class_wxCommandEvent","_wxCommandEvent",0}, { "_class_wxCommandEvent","_wxCommandEvent",0},
{ "_class_wxClientDC","_wxClientDC",0}, { "_class_wxClientDC","_wxClientDC",0},
{ "_class_wxSizeEvent","_wxSizeEvent",0}, { "_class_wxSizeEvent","_wxSizeEvent",0},
{ "_wxBrushList","_class_wxBrushList",0},
{ "_wxCustomDataObject","_class_wxCustomDataObject",0}, { "_wxCustomDataObject","_class_wxCustomDataObject",0},
{ "_class_wxLogNull","_wxLogNull",0}, { "_class_wxLogNull","_wxLogNull",0},
{ "_class_wxSize","_wxSize",0}, { "_class_wxSize","_wxSize",0},

View File

@@ -162,6 +162,23 @@ class wxWindowDisabler(wxWindowDisablerPtr):
class wxMutexGuiLockerPtr :
def __init__(self,this):
self.this = this
self.thisown = 0
def __del__(self,misc2c=misc2c):
if self.thisown == 1 :
misc2c.delete_wxMutexGuiLocker(self)
def __repr__(self):
return "<C wxMutexGuiLocker instance at %s>" % (self.this,)
class wxMutexGuiLocker(wxMutexGuiLockerPtr):
def __init__(self,*_args,**_kwargs):
self.this = apply(misc2c.new_wxMutexGuiLocker,_args,_kwargs)
self.thisown = 1
class wxTipProviderPtr : class wxTipProviderPtr :
def __init__(self,this): def __init__(self,this):
self.this = this self.this = this
@@ -716,11 +733,19 @@ wxCaret_GetBlinkTime = misc2c.wxCaret_GetBlinkTime
wxCaret_SetBlinkTime = misc2c.wxCaret_SetBlinkTime wxCaret_SetBlinkTime = misc2c.wxCaret_SetBlinkTime
wxSafeYield = misc2c.wxSafeYield
wxPostEvent = misc2c.wxPostEvent wxPostEvent = misc2c.wxPostEvent
wxWakeUpIdle = misc2c.wxWakeUpIdle wxWakeUpIdle = misc2c.wxWakeUpIdle
wxSafeYield = misc2c.wxSafeYield wxWakeUpMainThread = misc2c.wxWakeUpMainThread
wxMutexGuiEnter = misc2c.wxMutexGuiEnter
wxMutexGuiLeave = misc2c.wxMutexGuiLeave
wxThread_IsMain = misc2c.wxThread_IsMain
wxShowTip = misc2c.wxShowTip wxShowTip = misc2c.wxShowTip

View File

@@ -59,12 +59,12 @@ extern PyObject *SWIG_newvarlink(void);
static PyObject* l_output_helper(PyObject* target, PyObject* o) { static PyObject* l_output_helper(PyObject* target, PyObject* o) {
PyObject* o2; PyObject* o2;
if (!target) { if (!target) {
target = o; target = o;
} else if (target == Py_None) { } else if (target == Py_None) {
Py_DECREF(Py_None); Py_DECREF(Py_None);
target = o; target = o;
} else { } else {
if (!PyList_Check(target)) { if (!PyList_Check(target)) {
o2 = target; o2 = target;
target = PyList_New(0); target = PyList_New(0);
@@ -81,23 +81,23 @@ static PyObject* t_output_helper(PyObject* target, PyObject* o) {
PyObject* o2; PyObject* o2;
PyObject* o3; PyObject* o3;
if (!target) { if (!target) {
target = o; target = o;
} else if (target == Py_None) { } else if (target == Py_None) {
Py_DECREF(Py_None); Py_DECREF(Py_None);
target = o; target = o;
} else { } else {
if (!PyTuple_Check(target)) { if (!PyTuple_Check(target)) {
o2 = target; o2 = target;
target = PyTuple_New(1); target = PyTuple_New(1);
PyTuple_SetItem(target, 0, o2); PyTuple_SetItem(target, 0, o2);
} }
o3 = PyTuple_New(1); o3 = PyTuple_New(1);
PyTuple_SetItem(o3, 0, o); PyTuple_SetItem(o3, 0, o);
o2 = target; o2 = target;
target = PySequence_Concat(o2, o3); target = PySequence_Concat(o2, o3);
Py_DECREF(o2); Py_DECREF(o2);
Py_DECREF(o3); Py_DECREF(o3);
} }
return target; return target;
@@ -1829,6 +1829,7 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
{ "_wxPyProcess","_class_wxPyProcess",0}, { "_wxPyProcess","_class_wxPyProcess",0},
{ "_wxPyTreeCtrl","_class_wxPyTreeCtrl",0}, { "_wxPyTreeCtrl","_class_wxPyTreeCtrl",0},
{ "_wxImageHandler","_class_wxImageHandler",0}, { "_wxImageHandler","_class_wxImageHandler",0},
{ "_wxMutexGuiLocker","_class_wxMutexGuiLocker",0},
{ "_wxLog","_class_wxLog",0}, { "_wxLog","_class_wxLog",0},
{ "_class_wxToolBarBase","_wxToolBarBase",0}, { "_class_wxToolBarBase","_wxToolBarBase",0},
{ "_wxMask","_class_wxMask",0}, { "_wxMask","_class_wxMask",0},
@@ -1974,6 +1975,7 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
{ "_wxMessageDialog","_class_wxMessageDialog",0}, { "_wxMessageDialog","_class_wxMessageDialog",0},
{ "_class_wxValidator","_wxValidator",0}, { "_class_wxValidator","_wxValidator",0},
{ "_class_wxPyEvent","_wxPyEvent",0}, { "_class_wxPyEvent","_wxPyEvent",0},
{ "_class_wxMutexGuiLocker","_wxMutexGuiLocker",0},
{ "_wxTextEntryDialog","_class_wxTextEntryDialog",0}, { "_wxTextEntryDialog","_class_wxTextEntryDialog",0},
{ "_wxConfig","_class_wxConfig",0}, { "_wxConfig","_class_wxConfig",0},
{ "_class_wxIconizeEvent","_wxIconizeEvent",0}, { "_class_wxIconizeEvent","_wxIconizeEvent",0},

View File

@@ -1535,20 +1535,22 @@ class wxPyOnDemandOutputWindow:
self.title = title self.title = title
self.parent = None self.parent = None
def SetParent(self, parent): def SetParent(self, parent):
self.parent = parent self.parent = parent
def OnCloseWindow(self, event): def OnCloseWindow(self, event):
if self.frame != None: if self.frame != None:
self.frame.Destroy() self.frame.Destroy()
self.frame = None self.frame = None
self.text = None self.text = None
# These methods provide the file-like output behaviour.
# this provides the file-like output behaviour
def write(self, str): def write(self, str):
if not wxThread_IsMain():
# Aquire the GUI mutex before making GUI calls. Mutex is released
# when locker is deleted a the end of this function.
locker = wxMutexGuiLocker()
if not self.frame: if not self.frame:
self.frame = wxFrame(self.parent, -1, self.title) self.frame = wxFrame(self.parent, -1, self.title)
self.text = wxTextCtrl(self.frame, -1, "", self.text = wxTextCtrl(self.frame, -1, "",
@@ -1558,13 +1560,13 @@ class wxPyOnDemandOutputWindow:
EVT_CLOSE(self.frame, self.OnCloseWindow) EVT_CLOSE(self.frame, self.OnCloseWindow)
self.text.AppendText(str) self.text.AppendText(str)
def close(self): def close(self):
if self.frame != None: if self.frame != None:
if not wxThread_IsMain():
locker = wxMutexGuiLocker()
self.frame.Close() self.frame.Close()
_defRedirect = (wxPlatform == '__WXMSW__') _defRedirect = (wxPlatform == '__WXMSW__')
#---------------------------------------------------------------------- #----------------------------------------------------------------------

View File

@@ -0,0 +1,52 @@
from time import sleep
from threading import Thread
def test_a_window():
print "starting window thread"
from wxPython.wx import * # <-- the wxWin DLL is not loaded until here
app = wxPySimpleApp(1)
frame = wxFrame(None, -1, "Hello", size=(400,200))
frame.Show(true)
EVT_SIZE(frame, OnFrameSize)
app.MainLoop()
print "finishing window thread"
def OnFrameSize(evt):
print evt.GetSize()
keep_going = 1
def counter():
print "starting counter thread"
count = 0
while keep_going:
sleep(1)
count += 1
print count
print "finishing counter thread"
def main():
print "main startup"
ct = Thread(target=counter)
wt = Thread(target=test_a_window)
ct.start()
wt.start()
wt.join()
global keep_going
keep_going = 0
ct.join()
print "main finished"
main()