]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/demo/OOR.py
Implemented the first phase of OOR (Original Object Return). See the
[wxWidgets.git] / wxPython / demo / OOR.py
diff --git a/wxPython/demo/OOR.py b/wxPython/demo/OOR.py
new file mode 100644 (file)
index 0000000..3ef0878
--- /dev/null
@@ -0,0 +1,118 @@
+
+from wxPython.wx import *
+from wxPython.html import *
+
+#----------------------------------------------------------------------
+
+BTN1 = wxNewId()
+BTN2 = wxNewId()
+
+
+class TestPanel(wxPanel):
+    def __init__(self, parent, log):
+        wxPanel.__init__(self, parent, -1)
+        self.log = log
+
+        sizer = wxBoxSizer(wxVERTICAL)
+        html = wxHtmlWindow(self, -1)
+        html.SetPage(overview)
+        sizer.Add(html, 1, wxEXPAND|wxALL, 5)
+
+        btns = wxBoxSizer(wxHORIZONTAL)
+        btns.Add(50, -1, 1, wxEXPAND)
+        btn1 = wxButton(self, BTN1, "Find My Alter-ego")  # don't save a ref to this one
+        btns.Add(btn1)
+        btns.Add(50, -1, 1, wxEXPAND)
+        self.btn2 = wxButton(self, BTN2, "Find Myself")
+        btns.Add(self.btn2)
+        btns.Add(50, -1, 1, wxEXPAND)
+
+        sizer.Add(btns, 0, wxEXPAND|wxLEFT|wxRIGHT|wxBOTTOM, 5)
+
+        self.SetSizer(sizer)
+        self.SetAutoLayout(true)
+
+        EVT_BUTTON(self, BTN1, self.OnFindButton1)
+        EVT_BUTTON(self, BTN2, self.OnFindButton2)
+
+
+    def OnFindButton1(self, evt):
+        win = self.FindWindowById(BTN1)
+        if win is None:
+            self.log.write("***** OOPS! None returned...\n")
+            return
+        className = win.__class__.__name__
+        if className in ["wxButton", "wxButtonPtr"]:
+            self.log.write("The types are the same! <grin>\n")
+        else:
+            self.log.write("Got %s, expected wxButton or wxButtonPtr\n" % className)
+
+
+
+    def OnFindButton2(self, evt):
+        win = self.FindWindowById(BTN2)
+        if win is None:
+            self.log.write("***** OOPS! None returned...\n")
+            return
+        if win is self.btn2:
+            self.log.write("The objects are the same! <grin>\n")
+        else:
+            self.log.write("The objects are NOT the same! <frown>\n")
+
+
+#----------------------------------------------------------------------
+
+def runTest(frame, nb, log):
+    win = TestPanel(nb, log)
+    return win
+
+#----------------------------------------------------------------------
+
+
+overview = """\
+<html><body>
+<h2>Original Object Return</h2>
+
+<p>Several methods in wxWindows return pointers to base class objects,
+when in fact the actual object pointed to is of a derived type.  Since
+SWIG isn't able to tell the actual type it just creates a new Python
+shadow object of the base type to wrap around the base type pointer
+and returns it.
+
+<p>In wxPython this can cause annoying issues.  For example if you
+call:
+
+<pre>
+
+        myText = someWindow.FindWindowById(txtID)
+</pre>
+
+expecting to get a wxTextCtrl you will actually get a wxWindow object
+instead.  If you then try to call SetValue on that object you'll get
+an exception since there is no such method.  This is the reason for
+the wxPyTypeCast hack that has been in wxPython for so long.
+
+<p>Even with wxPyTypeCast there is the issue that the object returned
+is not the same one that was created in Python originally, but a new
+object of the same type that wraps the same C++ pointer.  If the
+programmer has set additional attributes of that original object they
+will not exist in the new object.
+
+<p>For a long time now I have wanted to do away with wxPyTypeCast and
+also find a way to return the original Python object from methods like
+FindWindowById.  This project naturally divides into two phases:
+
+<p><ol>
+
+<li>Teach the wrapper methods how to return objects of the right type,
+and be able to then turn wxPyTypeCast in to a no-op.
+
+<li>Be able to return the original Python shadow object if it still exists.
+
+</ol>
+
+<p>The first button below shows the first of these phases (<i>working</i>)
+and the second will show #2 (<i>not yet working.</i>)
+
+</body></html>
+"""