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:
parent
c1e820a40e
commit
6e18ca6cf4
@ -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
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -714,20 +714,22 @@ class wxPyOnDemandOutputWindow:
|
||||
self.title = title
|
||||
self.parent = None
|
||||
|
||||
|
||||
def SetParent(self, parent):
|
||||
self.parent = parent
|
||||
|
||||
|
||||
def OnCloseWindow(self, event):
|
||||
if self.frame != None:
|
||||
self.frame.Destroy()
|
||||
self.frame = None
|
||||
self.text = None
|
||||
|
||||
|
||||
# this provides the file-like output behaviour
|
||||
# These methods provide the file-like output behaviour.
|
||||
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:
|
||||
self.frame = wxFrame(self.parent, -1, self.title)
|
||||
self.text = wxTextCtrl(self.frame, -1, "",
|
||||
@ -737,13 +739,13 @@ class wxPyOnDemandOutputWindow:
|
||||
EVT_CLOSE(self.frame, self.OnCloseWindow)
|
||||
self.text.AppendText(str)
|
||||
|
||||
|
||||
def close(self):
|
||||
if self.frame != None:
|
||||
if not wxThread_IsMain():
|
||||
locker = wxMutexGuiLocker()
|
||||
self.frame.Close()
|
||||
|
||||
|
||||
|
||||
_defRedirect = (wxPlatform == '__WXMSW__')
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
@ -382,10 +382,28 @@ public:
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
bool wxSafeYield(wxWindow* win=NULL);
|
||||
void wxPostEvent(wxEvtHandler *dest, wxEvent& event);
|
||||
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();
|
||||
}
|
||||
%}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
@ -66,12 +66,12 @@ extern PyObject *SWIG_newvarlink(void);
|
||||
|
||||
static PyObject* l_output_helper(PyObject* target, PyObject* o) {
|
||||
PyObject* o2;
|
||||
if (!target) {
|
||||
if (!target) {
|
||||
target = o;
|
||||
} else if (target == Py_None) {
|
||||
} else if (target == Py_None) {
|
||||
Py_DECREF(Py_None);
|
||||
target = o;
|
||||
} else {
|
||||
} else {
|
||||
if (!PyList_Check(target)) {
|
||||
o2 = target;
|
||||
target = PyList_New(0);
|
||||
@ -88,23 +88,23 @@ static PyObject* t_output_helper(PyObject* target, PyObject* o) {
|
||||
PyObject* o2;
|
||||
PyObject* o3;
|
||||
|
||||
if (!target) {
|
||||
if (!target) {
|
||||
target = o;
|
||||
} else if (target == Py_None) {
|
||||
} else if (target == Py_None) {
|
||||
Py_DECREF(Py_None);
|
||||
target = o;
|
||||
} else {
|
||||
} else {
|
||||
if (!PyTuple_Check(target)) {
|
||||
o2 = target;
|
||||
target = PyTuple_New(1);
|
||||
PyTuple_SetItem(target, 0, o2);
|
||||
}
|
||||
o3 = PyTuple_New(1);
|
||||
PyTuple_SetItem(o3, 0, o);
|
||||
o3 = PyTuple_New(1);
|
||||
PyTuple_SetItem(o3, 0, o);
|
||||
|
||||
o2 = target;
|
||||
target = PySequence_Concat(o2, o3);
|
||||
Py_DECREF(o2);
|
||||
target = PySequence_Concat(o2, o3);
|
||||
Py_DECREF(o2);
|
||||
Py_DECREF(o3);
|
||||
}
|
||||
return target;
|
||||
@ -158,6 +158,10 @@ IMP_PYCALLBACK_BOOL_STRING(wxPyFontEnumerator, wxFontEnumerator, OnFacename);
|
||||
IMP_PYCALLBACK_BOOL_STRINGSTRING(wxPyFontEnumerator, wxFontEnumerator, OnFontEncoding);
|
||||
|
||||
|
||||
bool wxThread_IsMain() {
|
||||
return wxThread::IsMain();
|
||||
}
|
||||
|
||||
class wxPyTipProvider : public wxTipProvider {
|
||||
public:
|
||||
wxPyTipProvider(size_t currentTip)
|
||||
@ -1547,6 +1551,32 @@ static PyObject *_wrap_wxCaret_SetBlinkTime(PyObject *self, PyObject *args, PyOb
|
||||
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) {
|
||||
PyObject * _resultobj;
|
||||
wxEvtHandler * _arg0;
|
||||
@ -1599,26 +1629,68 @@ static PyObject *_wrap_wxWakeUpIdle(PyObject *self, PyObject *args, PyObject *kw
|
||||
return _resultobj;
|
||||
}
|
||||
|
||||
static PyObject *_wrap_wxSafeYield(PyObject *self, PyObject *args, PyObject *kwargs) {
|
||||
static PyObject *_wrap_wxWakeUpMainThread(PyObject *self, PyObject *args, PyObject *kwargs) {
|
||||
PyObject * _resultobj;
|
||||
bool _result;
|
||||
wxWindow * _arg0 = (wxWindow *) NULL;
|
||||
PyObject * _argo0 = 0;
|
||||
char *_kwnames[] = { "win", NULL };
|
||||
char *_kwnames[] = { NULL };
|
||||
|
||||
self = self;
|
||||
if(!PyArg_ParseTupleAndKeywords(args,kwargs,"|O:wxSafeYield",_kwnames,&_argo0))
|
||||
if(!PyArg_ParseTupleAndKeywords(args,kwargs,":wxWakeUpMainThread",_kwnames))
|
||||
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);
|
||||
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;
|
||||
} _resultobj = Py_BuildValue("i",_result);
|
||||
@ -3160,6 +3232,58 @@ static PyObject *_wrap_delete_wxWindowDisabler(PyObject *self, PyObject *args, P
|
||||
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)
|
||||
static PyObject *_wrap_delete_wxTipProvider(PyObject *self, PyObject *args, PyObject *kwargs) {
|
||||
PyObject * _resultobj;
|
||||
@ -6616,6 +6740,8 @@ static PyMethodDef misc2cMethods[] = {
|
||||
{ "wxTipProvider_GetCurrentTip", (PyCFunction) _wrap_wxTipProvider_GetCurrentTip, 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_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 },
|
||||
{ "new_wxWindowDisabler", (PyCFunction) _wrap_new_wxWindowDisabler, 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 },
|
||||
{ "wxCreateFileTipProvider", (PyCFunction) _wrap_wxCreateFileTipProvider, 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 },
|
||||
{ "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_GetBlinkTime", (PyCFunction) _wrap_wxCaret_GetBlinkTime, 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},
|
||||
{ "_wxNotifyEvent","_class_wxNotifyEvent",0},
|
||||
{ "_wxPyProcess","_class_wxPyProcess",0},
|
||||
{ "_wxMutexGuiLocker","_class_wxMutexGuiLocker",0},
|
||||
{ "_wxLog","_class_wxLogWindow",SwigwxLogWindowTowxLog},
|
||||
{ "_wxLog","_wxLogWindow",SwigwxLogWindowTowxLog},
|
||||
{ "_wxLog","_class_wxLogGui",SwigwxLogGuiTowxLog},
|
||||
@ -6760,6 +6891,7 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
|
||||
{ "_byte","_unsigned_char",0},
|
||||
{ "_wxDataObject","_class_wxDataObject",0},
|
||||
{ "_class_wxPyFontEnumerator","_wxPyFontEnumerator",0},
|
||||
{ "_wxColourDatabase","_class_wxColourDatabase",0},
|
||||
{ "_wxPyDataObjectSimple","_class_wxPyDataObjectSimple",0},
|
||||
{ "_wxPyDropSource","_class_wxPyDropSource",0},
|
||||
{ "_long","_unsigned_long",0},
|
||||
@ -6825,6 +6957,7 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
|
||||
{ "_class_wxWindowDisabler","_wxWindowDisabler",0},
|
||||
{ "_char","_wxChar",0},
|
||||
{ "_wxBitmap","_class_wxBitmap",0},
|
||||
{ "_wxPenList","_class_wxPenList",0},
|
||||
{ "_wxWindowDC","_class_wxWindowDC",0},
|
||||
{ "_wxTimerEvent","_class_wxTimerEvent",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_wxValidator","_wxValidator",0},
|
||||
{ "_class_wxPyEvent","_wxPyEvent",0},
|
||||
{ "_class_wxMutexGuiLocker","_wxMutexGuiLocker",0},
|
||||
{ "_class_wxIconizeEvent","_wxIconizeEvent",0},
|
||||
{ "_class_wxBusyCursor","_wxBusyCursor",0},
|
||||
{ "_wxDropTarget","_class_wxDropTarget",0},
|
||||
{ "_class_wxColourDatabase","_wxColourDatabase",0},
|
||||
{ "_wxScrollEvent","_class_wxScrollEvent",0},
|
||||
{ "_EBool","_wxCoord",0},
|
||||
{ "_EBool","_wxPrintQuality",0},
|
||||
@ -6854,8 +6989,10 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
|
||||
{ "_class_wxDC","_wxDC",0},
|
||||
{ "_wxScrollWinEvent","_class_wxScrollWinEvent",0},
|
||||
{ "_wxGenericDragImage","_class_wxGenericDragImage",0},
|
||||
{ "_class_wxBrushList","_wxBrushList",0},
|
||||
{ "_wxQueryNewPaletteEvent","_class_wxQueryNewPaletteEvent",0},
|
||||
{ "_wxPyInputStream","_class_wxPyInputStream",0},
|
||||
{ "_class_wxPenList","_wxPenList",0},
|
||||
{ "_class_wxWindowCreateEvent","_wxWindowCreateEvent",0},
|
||||
{ "_class_wxOutputStream","_wxOutputStream",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_wxCloseEvent","_wxCloseEvent",0},
|
||||
{ "_wxBusyInfo","_class_wxBusyInfo",0},
|
||||
{ "_wxFontList","_class_wxFontList",0},
|
||||
{ "_class_wxMenuEvent","_wxMenuEvent",0},
|
||||
{ "_wxPaletteChangedEvent","_class_wxPaletteChangedEvent",0},
|
||||
{ "_wxJoystick","_class_wxJoystick",0},
|
||||
@ -7020,10 +7158,12 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
|
||||
{ "_wxPyDropTarget","_class_wxPyDropTarget",0},
|
||||
{ "_wxActivateEvent","_class_wxActivateEvent",0},
|
||||
{ "_class_wxBusyInfo","_wxBusyInfo",0},
|
||||
{ "_class_wxFontList","_wxFontList",0},
|
||||
{ "_class_wxJoystick","_wxJoystick",0},
|
||||
{ "_class_wxCommandEvent","_wxCommandEvent",0},
|
||||
{ "_class_wxClientDC","_wxClientDC",0},
|
||||
{ "_class_wxSizeEvent","_wxSizeEvent",0},
|
||||
{ "_wxBrushList","_class_wxBrushList",0},
|
||||
{ "_wxCustomDataObject","_class_wxCustomDataObject",0},
|
||||
{ "_class_wxLogNull","_wxLogNull",0},
|
||||
{ "_class_wxSize","_wxSize",0},
|
||||
|
@ -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 :
|
||||
def __init__(self,this):
|
||||
self.this = this
|
||||
@ -716,11 +733,19 @@ wxCaret_GetBlinkTime = misc2c.wxCaret_GetBlinkTime
|
||||
|
||||
wxCaret_SetBlinkTime = misc2c.wxCaret_SetBlinkTime
|
||||
|
||||
wxSafeYield = misc2c.wxSafeYield
|
||||
|
||||
wxPostEvent = misc2c.wxPostEvent
|
||||
|
||||
wxWakeUpIdle = misc2c.wxWakeUpIdle
|
||||
|
||||
wxSafeYield = misc2c.wxSafeYield
|
||||
wxWakeUpMainThread = misc2c.wxWakeUpMainThread
|
||||
|
||||
wxMutexGuiEnter = misc2c.wxMutexGuiEnter
|
||||
|
||||
wxMutexGuiLeave = misc2c.wxMutexGuiLeave
|
||||
|
||||
wxThread_IsMain = misc2c.wxThread_IsMain
|
||||
|
||||
wxShowTip = misc2c.wxShowTip
|
||||
|
||||
|
@ -59,12 +59,12 @@ extern PyObject *SWIG_newvarlink(void);
|
||||
|
||||
static PyObject* l_output_helper(PyObject* target, PyObject* o) {
|
||||
PyObject* o2;
|
||||
if (!target) {
|
||||
if (!target) {
|
||||
target = o;
|
||||
} else if (target == Py_None) {
|
||||
} else if (target == Py_None) {
|
||||
Py_DECREF(Py_None);
|
||||
target = o;
|
||||
} else {
|
||||
} else {
|
||||
if (!PyList_Check(target)) {
|
||||
o2 = target;
|
||||
target = PyList_New(0);
|
||||
@ -81,23 +81,23 @@ static PyObject* t_output_helper(PyObject* target, PyObject* o) {
|
||||
PyObject* o2;
|
||||
PyObject* o3;
|
||||
|
||||
if (!target) {
|
||||
if (!target) {
|
||||
target = o;
|
||||
} else if (target == Py_None) {
|
||||
} else if (target == Py_None) {
|
||||
Py_DECREF(Py_None);
|
||||
target = o;
|
||||
} else {
|
||||
} else {
|
||||
if (!PyTuple_Check(target)) {
|
||||
o2 = target;
|
||||
target = PyTuple_New(1);
|
||||
PyTuple_SetItem(target, 0, o2);
|
||||
}
|
||||
o3 = PyTuple_New(1);
|
||||
PyTuple_SetItem(o3, 0, o);
|
||||
o3 = PyTuple_New(1);
|
||||
PyTuple_SetItem(o3, 0, o);
|
||||
|
||||
o2 = target;
|
||||
target = PySequence_Concat(o2, o3);
|
||||
Py_DECREF(o2);
|
||||
target = PySequence_Concat(o2, o3);
|
||||
Py_DECREF(o2);
|
||||
Py_DECREF(o3);
|
||||
}
|
||||
return target;
|
||||
@ -1829,6 +1829,7 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
|
||||
{ "_wxPyProcess","_class_wxPyProcess",0},
|
||||
{ "_wxPyTreeCtrl","_class_wxPyTreeCtrl",0},
|
||||
{ "_wxImageHandler","_class_wxImageHandler",0},
|
||||
{ "_wxMutexGuiLocker","_class_wxMutexGuiLocker",0},
|
||||
{ "_wxLog","_class_wxLog",0},
|
||||
{ "_class_wxToolBarBase","_wxToolBarBase",0},
|
||||
{ "_wxMask","_class_wxMask",0},
|
||||
@ -1974,6 +1975,7 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {
|
||||
{ "_wxMessageDialog","_class_wxMessageDialog",0},
|
||||
{ "_class_wxValidator","_wxValidator",0},
|
||||
{ "_class_wxPyEvent","_wxPyEvent",0},
|
||||
{ "_class_wxMutexGuiLocker","_wxMutexGuiLocker",0},
|
||||
{ "_wxTextEntryDialog","_class_wxTextEntryDialog",0},
|
||||
{ "_wxConfig","_class_wxConfig",0},
|
||||
{ "_class_wxIconizeEvent","_wxIconizeEvent",0},
|
||||
|
@ -1535,20 +1535,22 @@ class wxPyOnDemandOutputWindow:
|
||||
self.title = title
|
||||
self.parent = None
|
||||
|
||||
|
||||
def SetParent(self, parent):
|
||||
self.parent = parent
|
||||
|
||||
|
||||
def OnCloseWindow(self, event):
|
||||
if self.frame != None:
|
||||
self.frame.Destroy()
|
||||
self.frame = None
|
||||
self.text = None
|
||||
|
||||
|
||||
# this provides the file-like output behaviour
|
||||
# These methods provide the file-like output behaviour.
|
||||
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:
|
||||
self.frame = wxFrame(self.parent, -1, self.title)
|
||||
self.text = wxTextCtrl(self.frame, -1, "",
|
||||
@ -1558,13 +1560,13 @@ class wxPyOnDemandOutputWindow:
|
||||
EVT_CLOSE(self.frame, self.OnCloseWindow)
|
||||
self.text.AppendText(str)
|
||||
|
||||
|
||||
def close(self):
|
||||
if self.frame != None:
|
||||
if not wxThread_IsMain():
|
||||
locker = wxMutexGuiLocker()
|
||||
self.frame.Close()
|
||||
|
||||
|
||||
|
||||
_defRedirect = (wxPlatform == '__WXMSW__')
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
52
wxPython/tests/alternateThread.py
Normal file
52
wxPython/tests/alternateThread.py
Normal 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()
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user