X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a24268437fd8f5cf62e11ea3d386b14d38e6d981..b843b628c9f936d6a87ca1e9b91e88a4604270c4:/wxPython/samples/embedded/embedded.cpp diff --git a/wxPython/samples/embedded/embedded.cpp b/wxPython/samples/embedded/embedded.cpp index 73a79512c9..2805a649cf 100644 --- a/wxPython/samples/embedded/embedded.cpp +++ b/wxPython/samples/embedded/embedded.cpp @@ -1,6 +1,6 @@ //---------------------------------------------------------------------- // Name: embedded.cpp -// Purpose: To server as an example of how to use wxPython from +// Purpose: To serve as an example of how to use wxPython from // within a C++ wxWindows program. // // Author: Robin Dunn @@ -11,6 +11,9 @@ // Licence: wxWindows license //---------------------------------------------------------------------- +#include + + // For compilers that support precompilation, includes "wx/wx.h". #include @@ -29,8 +32,8 @@ #endif // Import Python and wxPython headers -#include -#include +#include + //---------------------------------------------------------------------- // Class definitions @@ -39,10 +42,10 @@ class MyApp : public wxApp { public: virtual bool OnInit(); - virtual ~MyApp(); - void Init_wxPython(); + virtual int OnExit(); + bool Init_wxPython(); private: - PyThreadState* main_tstate; + PyThreadState* m_mainTState; }; @@ -65,37 +68,54 @@ private: bool MyApp::OnInit() { - Init_wxPython(); + if ( !Init_wxPython() ) + // don't start the app if we can't initialize wxPython. + return false; + MyFrame *frame = new MyFrame(_T("Embedded wxPython Test"), - wxPoint(50, 50), wxSize(700, 600)); - frame->Show(TRUE); - return TRUE; + wxDefaultPosition, wxSize(700, 600)); + frame->Show(true); + return true; } -void MyApp::Init_wxPython() + +bool MyApp::Init_wxPython() { // Initialize Python Py_Initialize(); PyEval_InitThreads(); - // Load the wxPython core API. Imports the wxPython.wxc - // module and sets a pointer to a function table located there. - wxPyCoreAPI_IMPORT(); - + // Load the wxPython core API. Imports the wx._core_ module and sets a + // local pointer to a function table located there. The pointer is used + // internally by the rest of the API functions. + if ( ! wxPyCoreAPI_IMPORT() ) { + wxLogError(wxT("***** Error importing the wxPython API! *****")); + PyErr_Print(); + Py_Finalize(); + return false; + } + // Save the current Python thread state and release the // Global Interpreter Lock. - main_tstate = wxPyBeginAllowThreads(); + m_mainTState = wxPyBeginAllowThreads(); + + return true; } -MyApp::~MyApp() +int MyApp::OnExit() { // Restore the thread state and tell Python to cleanup after itself. - wxPyEndAllowThreads(main_tstate); + // wxPython will do its own cleanup as part of that process. This is done + // in OnExit instead of ~MyApp because OnExit is only called if OnInit is + // successful. + wxPyEndAllowThreads(m_mainTState); Py_Finalize(); + return 0; } + IMPLEMENT_APP(MyApp) //---------------------------------------------------------------------- @@ -108,8 +128,8 @@ enum BEGIN_EVENT_TABLE(MyFrame, wxFrame) - EVT_MENU(ID_EXIT, OnExit) - EVT_MENU(ID_PYFRAME, OnPyFrame) + EVT_MENU(ID_EXIT, MyFrame::OnExit) + EVT_MENU(ID_PYFRAME, MyFrame::OnPyFrame) END_EVENT_TABLE() @@ -122,10 +142,10 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) wxMenuBar* mbar = new wxMenuBar; wxMenu* menu = new wxMenu; - menu->Append(ID_PYFRAME, "Make wx&Python frame"); + menu->Append(ID_PYFRAME, _T("Make wx&Python frame")); menu->AppendSeparator(); - menu->Append(ID_EXIT, "&Close Frame\tAlt-X"); - mbar->Append(menu, "&File"); + menu->Append(ID_EXIT, _T("&Close Frame\tAlt-X")); + mbar->Append(menu, _T("&File")); SetMenuBar(mbar); CreateStatusBar(); @@ -133,10 +153,10 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) // Make some child windows from C++ wxSplitterWindow* sp = new wxSplitterWindow(this, -1); - wxPanel* p1 = new wxPanel(sp, -1); - p1->SetFont(wxFont(12, wxSWISS, wxNORMAL, wxBOLD)); + wxPanel* p1 = new wxPanel(sp, -1, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER); + new wxStaticText(p1, -1, - wxT("The frame, menu, splitter, this panel and this text were created in C++..."), + _T("The frame, menu, splitter, this panel and this text were created in C++..."), wxPoint(10,10)); // And get a panel from Python @@ -152,12 +172,12 @@ void MyFrame::OnExit(wxCommandEvent& event) //---------------------------------------------------------------------- -// This is were the fun begins... +// This is where the fun begins... char* python_code1 = "\ -from wxPython.wx import wxFrame\n\ -f = wxFrame(None, -1, 'Hello from wxPython!', size=(250, 150))\n\ +import wx\n\ +f = wx.Frame(None, -1, 'Hello from wxPython!', size=(250, 150))\n\ f.Show()\n\ "; @@ -167,16 +187,16 @@ void MyFrame::OnPyFrame(wxCommandEvent& event) // C++ code in any way, you can execute it with PyRun_SimpleString. - // First, whenever you do anyting with Python objects or code, you + // First, whenever you do anything with Python objects or code, you // *MUST* aquire the Global Interpreter Lock and block other // Python threads from running. - wxPyBeginBlockThreads(); + bool blocked = wxPyBeginBlockThreads(); // Execute the code in the __main__ module PyRun_SimpleString(python_code1); // Finally, release the GIL and let other Python threads run. - wxPyEndBlockThreads(); + wxPyEndBlockThreads(blocked); } @@ -187,19 +207,21 @@ void MyFrame::RedirectStdio() // only on demand when something is printed, like a traceback. char* python_redirect = "\ import sys\n\ -from wxPython.wx import wxPyOnDemandOutputWindow\n\ -output = wxPyOnDemandOutputWindow()\n\ +import wx\n\ +output = wx.PyOnDemandOutputWindow()\n\ sys.stdin = sys.stderr = output\n\ "; - wxPyBeginBlockThreads(); + bool blocked = wxPyBeginBlockThreads(); PyRun_SimpleString(python_redirect); - wxPyEndBlockThreads(); + wxPyEndBlockThreads(blocked); } char* python_code2 = "\ +import sys\n\ +sys.path.append('.')\n\ import embedded_sample\n\ \n\ def makeWindow(parent):\n\ @@ -212,7 +234,7 @@ wxWindow* MyFrame::DoPythonStuff(wxWindow* parent) // More complex embedded situations will require passing C++ objects to // Python and/or returning objects from Python to be used in C++. This // sample shows one way to do it. NOTE: The above code could just have - // easily come from a file, or the whole thing coupld be in the Python + // easily come from a file, or the whole thing could be in the Python // module that is imported and manipulated directly in this C++ code. See // the Python API for more details. @@ -220,7 +242,7 @@ wxWindow* MyFrame::DoPythonStuff(wxWindow* parent) PyObject* result; // As always, first grab the GIL - wxPyBeginBlockThreads(); + bool blocked = wxPyBeginBlockThreads(); // Now make a dictionary to serve as the global namespace when the code is // executed. Put a reference to the builtins module in it. (Yes, the @@ -235,7 +257,7 @@ wxWindow* MyFrame::DoPythonStuff(wxWindow* parent) // Was there an exception? if (! result) { PyErr_Print(); - wxPyEndBlockThreads(); + wxPyEndBlockThreads(blocked); return NULL; } Py_DECREF(result); @@ -250,7 +272,6 @@ wxWindow* MyFrame::DoPythonStuff(wxWindow* parent) // wxPython object that wraps it. PyObject* arg = wxPyMake_wxObject(parent); wxASSERT(arg != NULL); - PyObject* tuple = PyTuple_New(1); PyTuple_SET_ITEM(tuple, 0, arg); result = PyEval_CallObject(func, tuple); @@ -261,8 +282,8 @@ wxWindow* MyFrame::DoPythonStuff(wxWindow* parent) else { // Otherwise, get the returned window out of Python-land and // into C++-ville... - bool error = SWIG_GetPtrObj(result, (void**)&window, "_wxWindow_p"); - wxASSERT_MSG(!error, wxT("Returned object was not a wxWindow!")); + bool success = wxPyConvertSwigPtr(result, (void**)&window, _T("wxWindow")); + wxASSERT_MSG(success, _T("Returned object was not a wxWindow!")); Py_DECREF(result); } @@ -271,7 +292,7 @@ wxWindow* MyFrame::DoPythonStuff(wxWindow* parent) Py_DECREF(tuple); // Finally, after all Python stuff is done, release the GIL - wxPyEndBlockThreads(); + wxPyEndBlockThreads(blocked); return window; } @@ -284,95 +305,3 @@ wxWindow* MyFrame::DoPythonStuff(wxWindow* parent) - - - -// void MyFrame::OnButton(wxCommandEvent& WXUNUSED(event)) -// { -// //Py_Initialize(); -// //PySys_SetArgv(argc, argv) -// // // initialize thread support -// // PyEval_InitThreads(); -// wxPyBeginBlockThreads(); -// PyRun_SimpleString( -// "from wxPython.wx import *\n" -// "f = wxFrame(None, -1, 'Hello from wxPython', size=(250,150))\n" -// "f.Show()" -// ); -// wxPyEndBlockThreads(); -// } - - - - - - -// //////////////////////////////////////////////////////////////////////// -// //////////////////////////////////////////////////////////////////////// -// //////////////////////////////////////////////////////////////////////// -// /// this, RedirectIOToConsole(), help came from -// /// http://www.halcyon.com/ast/dload/guicon.htm - -// // #include -// // #include -// #include -// #include -// // #include -// // #include -// // //#ifndef _USE_OLD_IOSTREAMS -// // using namespace std; -// // //#endif - -// // maximum mumber of lines the output console should have -// static const WORD MAX_CONSOLE_LINES = 500; - -// void RedirectIOToConsole() -// { -// int hConHandle; -// long lStdHandle; -// CONSOLE_SCREEN_BUFFER_INFO coninfo; -// FILE *fp; - -// // allocate a console for this app -// AllocConsole(); - -// // set the screen buffer to be big enough to let us scroll text -// GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); - -// coninfo.dwSize.Y = MAX_CONSOLE_LINES; -// SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize); - -// // redirect unbuffered STDOUT to the console -// lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE); -// hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); - -// fp = _fdopen( hConHandle, "w" ); -// *stdout = *fp; - -// setvbuf( stdout, NULL, _IONBF, 0 ); - -// // redirect unbuffered STDIN to the console -// lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE); -// hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); - -// fp = _fdopen( hConHandle, "r" ); -// *stdin = *fp; - -// setvbuf( stdin, NULL, _IONBF, 0 ); - -// // redirect unbuffered STDERR to the console -// lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE); -// hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); - -// fp = _fdopen( hConHandle, "w" ); -// *stderr = *fp; -// setvbuf( stderr, NULL, _IONBF, 0 ); - -// // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog -// // point to console as well -// //std::ios::sync_with_stdio(); -// } - -// //////////////////////////////////////////////////////////////////////// -// //////////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////////////