mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2025-12-16 09:40:07 +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="""\
|
||||
success = 0
|
||||
for et in self.evtType:
|
||||
success += target.Disconnect(id1, id2, et, handler)
|
||||
success += int(target.Disconnect(id1, id2, et, handler))
|
||||
return success != 0
|
||||
"""),
|
||||
|
||||
@@ -196,8 +196,7 @@ def run():
|
||||
body="""\
|
||||
if (PyCallable_Check(func)) {
|
||||
self->Connect(id, lastId, eventType,
|
||||
(wxObjectEventFunction)(wxEventFunction)
|
||||
&wxPyCallback::EventThunker,
|
||||
(wxObjectEventFunction)&wxPyCallback::EventThunker,
|
||||
new wxPyCallback(func));
|
||||
}
|
||||
else if (func == Py_None) {
|
||||
@@ -219,7 +218,7 @@ def run():
|
||||
body="""\
|
||||
if (func && func != Py_None) {
|
||||
// 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
|
||||
// have to do the searching ourselves...
|
||||
wxList::compatibility_iterator node = self->GetDynamicEventTable()->GetFirst();
|
||||
@@ -229,12 +228,15 @@ def run():
|
||||
if ((entry->m_id == id) &&
|
||||
((entry->m_lastId == lastId) || (lastId == wxID_ANY)) &&
|
||||
((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) &&
|
||||
// FIXME?
|
||||
//((entry->m_fn->IsMatching((wxObjectEventFunction)(wxEventFunction)&wxPyCallback::EventThunker))) &&
|
||||
entry->m_fn->IsMatching(wxObjectEventFunctor((wxObjectEventFunction)&wxPyCallback::EventThunker, NULL)) &&
|
||||
(entry->m_callbackUserData != NULL))
|
||||
{
|
||||
wxPyThreadBlocker block;
|
||||
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;
|
||||
self->GetDynamicEventTable()->Erase(node);
|
||||
delete entry;
|
||||
@@ -247,8 +249,7 @@ def run():
|
||||
}
|
||||
else {
|
||||
return self->Disconnect(id, lastId, eventType,
|
||||
(wxObjectEventFunction)
|
||||
&wxPyCallback::EventThunker);
|
||||
(wxObjectEventFunction)&wxPyCallback::EventThunker);
|
||||
}
|
||||
""")
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import unittest
|
||||
from unittests import wtc
|
||||
import wx
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
class Events(unittest.TestCase):
|
||||
class Events(wtc.WidgetTestCase):
|
||||
|
||||
# Test the constructors to make sure the classes are not abstract, except
|
||||
# for wx.Event
|
||||
@@ -45,7 +46,6 @@ class Events(unittest.TestCase):
|
||||
evt = wx.FocusEvent()
|
||||
|
||||
def test_HelpEvent_ctor(self):
|
||||
app = wx.App()
|
||||
evt = wx.HelpEvent()
|
||||
|
||||
def test_IconizeEvent_ctor(self):
|
||||
@@ -138,14 +138,88 @@ class Events(unittest.TestCase):
|
||||
def OnSize(self, evt):
|
||||
self.gotEvent = True
|
||||
evt.EventObject.Close()
|
||||
app = wx.App()
|
||||
frm = Frame(None)
|
||||
frm.Show()
|
||||
frm.SetSize((200,100))
|
||||
#app.MainLoop()
|
||||
self.myYield()
|
||||
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):
|
||||
evt = wx.DropFilesEvent(123, 'one two three four five'.split())
|
||||
self.assertTrue(evt.NumberOfFiles == 5)
|
||||
|
||||
Reference in New Issue
Block a user