mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-05 03:20:08 +01:00
Fix our wxEvtHandler::Disconnect replacement
* Fix C++ compare of the handler functor * Use PyObject_RichCompare to check for matching python handlers
This commit is contained in:
19
etg/event.py
19
etg/event.py
@@ -128,7 +128,7 @@ def run():
|
|||||||
body="""\
|
body="""\
|
||||||
success = 0
|
success = 0
|
||||||
for et in self.evtType:
|
for et in self.evtType:
|
||||||
success += target.Disconnect(id1, id2, et, handler)
|
success += int(target.Disconnect(id1, id2, et, handler))
|
||||||
return success != 0
|
return success != 0
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
@@ -196,8 +196,7 @@ def run():
|
|||||||
body="""\
|
body="""\
|
||||||
if (PyCallable_Check(func)) {
|
if (PyCallable_Check(func)) {
|
||||||
self->Connect(id, lastId, eventType,
|
self->Connect(id, lastId, eventType,
|
||||||
(wxObjectEventFunction)(wxEventFunction)
|
(wxObjectEventFunction)&wxPyCallback::EventThunker,
|
||||||
&wxPyCallback::EventThunker,
|
|
||||||
new wxPyCallback(func));
|
new wxPyCallback(func));
|
||||||
}
|
}
|
||||||
else if (func == Py_None) {
|
else if (func == Py_None) {
|
||||||
@@ -219,7 +218,7 @@ def run():
|
|||||||
body="""\
|
body="""\
|
||||||
if (func && func != Py_None) {
|
if (func && func != Py_None) {
|
||||||
// Find the current matching binder that has this function
|
// Find the current matching binder that has this function
|
||||||
// pointer and dissconnect that one. Unfortuneatly since we
|
// pointer and disconnect that one. Unfortunately since we
|
||||||
// wrapped the PyObject function pointer in another object we
|
// wrapped the PyObject function pointer in another object we
|
||||||
// have to do the searching ourselves...
|
// have to do the searching ourselves...
|
||||||
wxList::compatibility_iterator node = self->GetDynamicEventTable()->GetFirst();
|
wxList::compatibility_iterator node = self->GetDynamicEventTable()->GetFirst();
|
||||||
@@ -229,12 +228,15 @@ def run():
|
|||||||
if ((entry->m_id == id) &&
|
if ((entry->m_id == id) &&
|
||||||
((entry->m_lastId == lastId) || (lastId == wxID_ANY)) &&
|
((entry->m_lastId == lastId) || (lastId == wxID_ANY)) &&
|
||||||
((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) &&
|
((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) &&
|
||||||
// FIXME?
|
entry->m_fn->IsMatching(wxObjectEventFunctor((wxObjectEventFunction)&wxPyCallback::EventThunker, NULL)) &&
|
||||||
//((entry->m_fn->IsMatching((wxObjectEventFunction)(wxEventFunction)&wxPyCallback::EventThunker))) &&
|
|
||||||
(entry->m_callbackUserData != NULL))
|
(entry->m_callbackUserData != NULL))
|
||||||
{
|
{
|
||||||
|
wxPyThreadBlocker block;
|
||||||
wxPyCallback *cb = (wxPyCallback*)entry->m_callbackUserData;
|
wxPyCallback *cb = (wxPyCallback*)entry->m_callbackUserData;
|
||||||
if (cb->m_func == func) {
|
// NOTE: Just comparing PyObject pointers is not enough, as bound
|
||||||
|
// methods can result in different PyObjects each time obj.Method
|
||||||
|
// is evaluated. (!!!)
|
||||||
|
if (PyObject_RichCompareBool(cb->m_func, func, Py_EQ) == 1) {
|
||||||
delete cb;
|
delete cb;
|
||||||
self->GetDynamicEventTable()->Erase(node);
|
self->GetDynamicEventTable()->Erase(node);
|
||||||
delete entry;
|
delete entry;
|
||||||
@@ -247,8 +249,7 @@ def run():
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return self->Disconnect(id, lastId, eventType,
|
return self->Disconnect(id, lastId, eventType,
|
||||||
(wxObjectEventFunction)
|
(wxObjectEventFunction)&wxPyCallback::EventThunker);
|
||||||
&wxPyCallback::EventThunker);
|
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
from unittests import wtc
|
||||||
import wx
|
import wx
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
class Events(unittest.TestCase):
|
class Events(wtc.WidgetTestCase):
|
||||||
|
|
||||||
# Test the constructors to make sure the classes are not abstract, except
|
# Test the constructors to make sure the classes are not abstract, except
|
||||||
# for wx.Event
|
# for wx.Event
|
||||||
@@ -45,7 +46,6 @@ class Events(unittest.TestCase):
|
|||||||
evt = wx.FocusEvent()
|
evt = wx.FocusEvent()
|
||||||
|
|
||||||
def test_HelpEvent_ctor(self):
|
def test_HelpEvent_ctor(self):
|
||||||
app = wx.App()
|
|
||||||
evt = wx.HelpEvent()
|
evt = wx.HelpEvent()
|
||||||
|
|
||||||
def test_IconizeEvent_ctor(self):
|
def test_IconizeEvent_ctor(self):
|
||||||
@@ -138,14 +138,88 @@ class Events(unittest.TestCase):
|
|||||||
def OnSize(self, evt):
|
def OnSize(self, evt):
|
||||||
self.gotEvent = True
|
self.gotEvent = True
|
||||||
evt.EventObject.Close()
|
evt.EventObject.Close()
|
||||||
app = wx.App()
|
|
||||||
frm = Frame(None)
|
frm = Frame(None)
|
||||||
frm.Show()
|
frm.Show()
|
||||||
frm.SetSize((200,100))
|
frm.SetSize((200,100))
|
||||||
#app.MainLoop()
|
self.myYield()
|
||||||
self.assertTrue(frm.gotEvent)
|
self.assertTrue(frm.gotEvent)
|
||||||
|
|
||||||
|
|
||||||
|
def test_eventUnbinding1(self):
|
||||||
|
"Unbind without specifying handler"
|
||||||
|
self.gotEvent = False
|
||||||
|
|
||||||
|
def _onSize(evt):
|
||||||
|
self.gotEvent = True
|
||||||
|
|
||||||
|
self.frame.Bind(wx.EVT_SIZE, _onSize)
|
||||||
|
val = self.frame.Unbind(wx.EVT_SIZE)
|
||||||
|
assert val, "Unbind returned false"
|
||||||
|
|
||||||
|
self.frame.SetSize((200,200))
|
||||||
|
self.myYield()
|
||||||
|
assert not self.gotEvent, "Expected gotEvent to still be False"
|
||||||
|
|
||||||
|
|
||||||
|
def test_eventUnbinding2(self):
|
||||||
|
"Unbind with specifying handler, simple function object"
|
||||||
|
self.gotEvent = False
|
||||||
|
|
||||||
|
def _onSize(evt):
|
||||||
|
self.gotEvent = True
|
||||||
|
|
||||||
|
self.frame.Bind(wx.EVT_SIZE, _onSize)
|
||||||
|
val = self.frame.Unbind(wx.EVT_SIZE, handler=_onSize)
|
||||||
|
assert val, "Unbind returned False"
|
||||||
|
|
||||||
|
self.frame.SetSize((200,200))
|
||||||
|
self.myYield()
|
||||||
|
assert not self.gotEvent, "Expected gotEvent to still be False"
|
||||||
|
|
||||||
|
|
||||||
|
def test_eventUnbinding3(self):
|
||||||
|
"Unbind with specifying handler, a bound method"
|
||||||
|
|
||||||
|
class Frame(wx.Frame):
|
||||||
|
def __init__(self, *args, **kw):
|
||||||
|
wx.Frame.__init__(self, *args, **kw)
|
||||||
|
self.Bind(wx.EVT_SIZE, self.OnSize)
|
||||||
|
self.gotEvent = False
|
||||||
|
self.obj = self.OnSize
|
||||||
|
|
||||||
|
def doUnBind(self):
|
||||||
|
#assert id(self.obj) != id(self.OnSize) # Strange, but it's possible
|
||||||
|
val = self.Unbind(wx.EVT_SIZE, handler=self.OnSize)
|
||||||
|
assert val, "Unbind returned False"
|
||||||
|
|
||||||
|
def OnSize(self, evt):
|
||||||
|
self.gotEvent = True
|
||||||
|
evt.EventObject.Close()
|
||||||
|
|
||||||
|
frm = Frame(None)
|
||||||
|
frm.doUnBind()
|
||||||
|
frm.Show()
|
||||||
|
frm.SetSize((200,100))
|
||||||
|
self.myYield()
|
||||||
|
assert not frm.gotEvent, "Expected gotEvent to still be False"
|
||||||
|
|
||||||
|
|
||||||
|
def test_eventUnbinding4(self):
|
||||||
|
"Unbind by passing None to Bind()"
|
||||||
|
self.gotEvent = False
|
||||||
|
|
||||||
|
def _onSize(evt):
|
||||||
|
self.gotEvent = True
|
||||||
|
|
||||||
|
self.frame.Bind(wx.EVT_SIZE, _onSize)
|
||||||
|
self.frame.Bind(wx.EVT_SIZE, None)
|
||||||
|
|
||||||
|
self.frame.SetSize((200,200))
|
||||||
|
self.myYield()
|
||||||
|
assert not self.gotEvent, "Expected gotEvent to still be False"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_DropFilesEvent_tweaks(self):
|
def test_DropFilesEvent_tweaks(self):
|
||||||
evt = wx.DropFilesEvent(123, 'one two three four five'.split())
|
evt = wx.DropFilesEvent(123, 'one two three four five'.split())
|
||||||
self.assertTrue(evt.NumberOfFiles == 5)
|
self.assertTrue(evt.NumberOfFiles == 5)
|
||||||
|
|||||||
Reference in New Issue
Block a user