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:
@@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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__')
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
@@ -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();
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@@ -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},
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
@@ -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},
|
||||||
|
@@ -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__')
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user