Question 1. How Do I Build Wxpython On Unix?
This file describes how I build wxWidgets and wxPython while doing development and testing, and is meant to help other people that want to do the same thing. Those readers who have attempted this in previous releases of the software will probably notice that this file is much smaller than it was before. Much thanks for this goes to Kevin Ollivier who wrote the initial version of the new build scripts and then guilted me into starting to use and maintain them myself.
Building of both wxWidgets and wxPython is now handled by the wxPython/build-wxpython.py script in the source tree. It takes care of all the nasty and confusing details that used to be documented in this file. Pretty much all you need to worry about now is having the build tools and dependent libraries installed on your system and specifying where to install the results, if other than the standard location.
If you want to make changes to any of the *.i files, (SWIG interface definition files,) then you will need to use a special patched version of SWIG. Get the sources for version 1.3.29, and then apply the patches in wxPython/SWIG and then build SWIG like normal. See the README.txt in the wxPython/SWIG dir for details about each patch.
If you install this build of SWIG to a location that is not on the PATH (so it doesn’t interfere with an existing SWIG install for example) then you can set a SWIG environment variable to the full path of this new binary to tell the build script which SWIG to use.
Question 2. How Do I Build Wxpython On Windows?
The Windows builds currently require the use of Microsoft Visual C++. Theoretically, other compilers (such as mingw32 or the Borland compilers) can also be used but I’ve never done the work to make that happen. If you want to try that then first you’ll want to find out if there are any tricks that have to be done to make Python extension modules using that compiler, and then make a few changes to setup.py to accommodate that. (And send the patches to me.) If you plan on using VisualStudio.Net (a.k.a. MSVC 7.1) keep in mind that you’ll also have to build Python and any other extension modules that you use with that compiler because a different version of the C runtime library is used. The Python executable that comes from PythonLabs and the wxPython extensions that I distribute are built with MSVC 6 with all the Service Packs applied. This policy will change with Python 2.4 and MSVC 7.1 will be used starting with that version.
If you want to build a debuggable version of wxWidgets and wxPython you will need to have also built a debug version of Python and any other extension modules you need to use. You can tell if you have them already if there is a _d in the file names, for example python_d.exe or python23_d.dll. If you don’t need to trace through the C/C++ parts of the code with the debugger then building the normal (or hybrid) version is fine, and you can use the regular python executables with it.
Starting with 188.8.131.52 wxPython can be built for either the monlithic or the multi-lib wxWidgets builds. (Monolithic means that all the core wxWidgets code is in one DLL, and multi-lib means that the core code is divided into multiple DLLs.) To select which one to use specify the MONOLITHIC flag for both the wxWidgets build and the wxPython build as shown below, setting it to either 0 or 1.
Just like the unix versions I also use some scripts to help me build wxWidgets, but I use some non-standard stuff to do it. So if you have bash (cygwin or probably MSYS too) or 4NT plus unix-like cat and sed programs then there is a copy of my wxWidgets build scripts in %WXDIR%wxPythondistribmsw. Just copy them to %WXDIR%buildmsw and you can use them to do your build, otherwise you can do everything by hand as described below. But if you do work by hand and something doesn’t seem to be working correctly please refer to the build scripts to see what may need to be done differently.
Question 3. Python Crashes In Kernel32.dll When I Import Wxpython In Windows 95?
You can probably fix this by installing winsock2
Question 4. I Don’t Know C++, How Can I Use The Docs?
Apart from the “wxPython Notes” and some articles under “Topic Overview” which you may find useful, the most important parts of the wxPython documentation, for the Python programmer, are:
- The Alphabetical Class Reference
- The list of Functions
This is the information which you’ll need to refer to again and again as you’re developing your wxPython apps. Unfortunately, though, these references are written for C++ programmers, so virtually all the method and function definitions are in C++ format, which makes it hard for a Python programmer to make sense of.
Question 5. I Ran “python Demo.py” And All I Got Was This:
Traceback (most Recent Call Last):
File “demo.py”, Line 3, In ?
File “main.py”, Line 15, In ?
From Wxpython.wx Import *
Importerror: No Module Named Wxpython.wx
When I Did A Search Of My Whole Python Directory, I Found No File Named Wxpython.wx.
In this context the dot means that it is looking for a module named wx located in a Python package named wxPython. Translated to the filesystem that means a directory named wxPython with a file named wx.py located within it. And an empty file named “init.py” to make this folder a package.
This error message means that the wxPython directory is not located in a directory that is in the PYTHONPATH. To check your path run this from within Python:
If the directory containing the wxPython directory is not there you either need to move wxPython or add the directory to PYTHONPATH. This can be done either in the environment, in a sitecustomize.py file (that is on the default path) on in the registry on Win32. See the Python docs for more details.
On Linux the wxPython RPM for Python 2 puts wxPython in /usr/local/lib/python2.0/site-packages since Python 2 was installed in /usr/local on my build system. If Python 2 is in /usr on your system then you’ll want to move (or link) wxPython to /usr/lib/python2.0/site-packages.
On Win32 wxPython will install to the Python directory by default, which is automatically on the PYTHONPATH, so Python will be able to find the modules using the above syntax. If you installed somewhere else then you need to add that directory to the PYTHONPATH as described above.
Question 6. Can I Use Wxpython Binaries With A Different Version Of Python?
In general, no. You need to use the same version of Python as the wxPython binary was built with. That is why the version is part of the filename.
Question 7. I’ve Looked At Tkinter And At Wxpython. Why Would I Choose One Or The Other?
Installation: tkInter is a GUI toolkit that has been distributed widely with Python, and is readily available to everyone who is running Python. wxPython requires an additional install on top of the Python install. If it’s just for your own machine, this isn’t a big deal, but if you have a lot of people who need it, this could become a bit of a big deal.
Native Look and Feel: wxPython supports the native look and feel of the platform being used. tkInter has its own look and feel for some components, which doesn’t match any standard platform.
Windows XP and Python 2.2.2: In Python 2.2.2 under Windows XP you need this additional step:
Put two files python.exe.manifest and pythonw.exe.manifest, both with the following contents:
version=”184.108.40.206″ processorArchitecture=”X86″ publicKeyToken=”6595b64144ccf1df” language=”*” />
in your Python installation directory (where respective .exe files reside). Next time you run your wxPython applications, they’ll look like “normal” XP applications.
This may also affect other Python modules that use Windows display API.
If you are using py2exe to build a standalone Python executable, say FOO.EXE, you need to copy pythonw.exe.manifest into the directory where FOO.EXE is and name it FOO.EXE.manifest.
Wide Range of Available Widgets: wxPython has a much wider range of available widgets than does tkInter. There are additions available for tkInter that somewhat mitigate this situation, but this destroys the convenience argument for tkInter. In addition, the wxPython toolkit has support for printing and other non-GUI, but also non-standard operations. tkInter is fine if your application is simply a way of interacting with the user via a GUI, but if you need to develop a full-scale application with support for drawing your own UI elements, support for printing, etc., wxPython is definitely the way to go.
Question 8. Is There A Mailing List For Help?
Yes. You can subscribe to the list, and read the archives.
Question 9. How Do I Get Help From The Wxpython-users Mailing List?
When you have a unique problem, it is time to ask a question on wxPython-users. Please conform to the basic rules of netiquet. Aside from them, there is one thing you can do to improve your chances of getting a helpful answer if you have some idea how to do something, but it’s not quite working:
Send a Complete, Working App that demonstrates your problem or question. This app should be complete, in that it can be run, but as small as possible, so that it isolates your problem, and gives those of us that read the list as little to look at as possible.
This accomplishes two things:
- When isolating your problem, you might just find out why it wasn’t working.
It makes it MUCH easier for us to help you, for a number of reasons:
- We can just run the app and see how it’s behaving.
- We can easily tweak it, and try to find a solution.
- Your problem may not be where you think it is. If you don’t send a complete version, your problem may not be in the code you send, or be a function of how that code is used.
Question 10. What Is The Difference Between A Wxframe And A Wxwindow? When Do I Want To Use Each One?
The terminology is a bit confusing. a wxFrame is what most folks think of as a Window: a box on the screen that holds your application, etc. It can be re-sized, moved, etc with the mouse by the window manager of the system.
A wxWindow is the basic unit from which all the controls, etc. are built. It is a rectangle on the screen that captures mouse clicks, draws itself etc. a wxWindow will almost always be put into a Frame or other window.
You want to use a frame to create an independent box on the screen to house some part of your application. You want to use a wxWindow as the basis for a custom control of your own design. All the built-in controls are derived from a wxWindow already.
Question 11. How Do I Use Multiple Threads?
All calls to methods of GUI objects and event handlers need to happen on the main thread. In wxPython the main thread is the one that first imports the wxPython.wx module. Other threads can send events to the main thread using wxPostEvent as is done in the Threads sample in the wxPython demo.
Question 12. How Are Multiple Evt_xxx Calls Handled?
- I am wondering about how EVT_XXX handles multiple calls. I want to change
- how events are handled depending upon which mode my program is in. If I call
- EVT_XXX multiple times for the same event, each time pointing to a different
- method, are these event handlers chained or do subsequent calls replace the
- old event handler?
Each instance of a class derived from wxEvt
Handler has a static event table, which is used only by C++ code, and a dynamic event table (just a list really) which is what wxPython uses although a few C++ developers use it too. Every time you call a EVT_XXX function it adds an entry to this list. When an event happens the first matching handler in the event table is called, and if it calls event.Skip() then the search continues so if another match is found then it is called too. The EVT_XXX functions are really just convenience wrappers around the wxEvt
Handler.Connect method. There is also a .Disconnect method that you can call if needed to remove an event handler binding.
Question 13. How Can I Use A Visual Debugger With Wxpython ?
Most Debuggers (like IDLE or Python Win) use a different GUI toolkit than wxPython does, and some debug the wxPython app within their own process. This creates lots of conflicts between the wxPython event loop and the event loop of the debuggers’ GUI tookit.
So, you need a debugger that debugs your program out-of-process. At present, HAP, Wing IDE and Komodo do so. HAP is open-source, so you might be interested in checking that one out;
Question 14. How Do I Remove A Component, Or All Components Of A Certain Type From A Wxframe/wxpanel?
If your container is using a sizer, you can remove all its children with this function:
Toggle line numbers
- def removeChildren(self, destroy=1):
- Remove all my children components and optionally
- destroy them.
- while self.GetSizer().Remove(0):
- if destroy:
To only remove children of a particular kind (ie.wxStaticText), you could add a parameter to the method, and do an isinstance() test.
Question 15. How Do I Get A Wxgrid To Update Its Scrollbars?
In wxPython 220.127.116.11, wxGrid apparently does not update its scroll bars in response to changes in the rows and columns. You can cause it to do this by callingFitInside() on the wxGrid object.
Question 16. How Do I Hide The Row And Column Labels In A Wxgrid Window?
Set the size to 0. The label windows will still exist, but they will not be visible.
(thanks PaulMcNett for the info)
Question 17. What’s The Difference Between All The Dc Types?
wxPaintDC can only be used inside a EVT_PAINT event and has extra info about what regions of the window have been damaged and need to be refreshed, allowing some optimization of the re-draw. You can also use this information to optimize your redraw if you want.
wxClientDC can be used anytime for drawing to the window, but you must ensure that whatever you draw then is also redrawn in a EVT_PAINT event otherwise it will get lost the next time the window is refreshed. This is useful if you want to update the screen as a result of some other action, and can be used to display animations, etc.
wxMemoryDC allows you to draw to a wxBitmap instead of to a window. The resulting wxBitmap can be used for a variety of things, including an off screen buffer of what is on screen.
wxBufferedDC and wxBufferedPaintDC are simple convenience classes that derive from wxMemoryDC. You give it a buffer bitmap and then all drawing goes to the bitmap. When the last reference to the buffered dc goes out of scope or is deleted then the contents of the bitmap are dumped to the real DC (if any) that you gave to the buffered dc when you constructed it. This helps to reduce flicker and such for complex drawings. and also reduces the time needed for EVT_PAINT handlers because all they are doing is drawing the buffer bitmap, not a whole complex drawing. You can easily do the same thing yourself without the buffered DCs with just a wxMemoryDC, a bitmap and a DrawBitmap call.
Question 18. Why Doesn’t The Getstring Method Of Wxcommandevent Work?
Many simple controls like buttons, list boxes, check boxes, etc., generate a wxCommandEvent, because the event is often processed by the parent window, and only command events propogate to the parent (if the control itself doesn’t handle them). However, because the values needed by the event handler vary depending on the type of the control and on the specific event, wxCommandEvent has a variety of different methods for retrieving the value. Depending on the control and event, not all these methods will return non-zero or non-empty values. For example, GetString only works for EVT_LISTBOX and EVT_CHOICE, but doesn’t make any sense for EVT_CHECKBOX. Read the documentation of the wxCommandEvent method for details of which events support that method. If you need additional information, you’ll need to retrieve a reference to the control which generated the event (see How can my EVT_XYZ handler find the control that generated an event?)
Question 19. Why Do The Paths To My Resource Files Work In Testing, But Fail After Installation On Windows?
This is a known problem. In testing, the relative paths point to the files correctly, but after installation the relative paths do not point to the intended location. To remedy this, you will need to provide a dynamic absolute path to the resource files.
Insert the following code in your main Python file:
# Sets the homepath variable (you can change the name) to the directory where your application is located (sys.argv).
__builtin__.__dict__[‘homepath’] = os.path.abspath(os.path.dirname(sys.argv))
Whenever you need to load a resource file, you have to append homepath as follows, using os.path.join(). Your application will now load directory names correctly in both testing and post-installation.
toolbar.AddSimpleTool(1, wx.Image(os.path.join(homepath, ‘resfilenew.png’), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), ‘New’, ”)
Question 20. How Can My Evt_xyz Handler Find The Control That Generated An Event?
The event your handler receives will be of a class derived from wxEvent, which has a GetEventObject method. In the case of an event generated by a control, calling GetEventObject() on the event will return a reference to the control.
Question 21. How Do I Embed Images In Python Code?
Use img2py.py from the tools folder of your wxPython installation. It converts an image file to .png format, compresses it, and stores the binary data in a .py file with routines to load the image.
Question 22. How Do I Keep Wxpython From Redirecting Errors And Exceptions To A Gui Window?
Quoting from Getting Started
- When a python program hits an unhandled exception (bug!) in your program, it aborts with a traceback that is useful in locating the source of the problem. wxPython programs do the same, but with a twist. The traceback is routed to stdio, which is captured in a nice GUI frame independent of your program. If an exception shows up in an event handler, the traceback is displayed, and your program continues on as best it can. BUT, if the exception occurs while initializing your program, the traceback will show up, and then your program will abort, taking the stdio window (and your traceback) with it before even the fastest reader can make sense of it.
- You can keep stdio from being hijacked by wxPython by providing a couple of optional parameters when you instantiate your wxApp. An example says it best:
Toggle line numbers
- myapp = MyApp() # functions normally. Stdio is redirected to its own window
- myapp = MyApp(0) #does not redirect stdout. Tracebacks will show up at the console.
- myapp = MyApp(1, ‘filespec’) #redirects stdout to the file ‘filespec’
- # NOTE: These are named parameters, so you can do this for improved readability:
- myapp = MyApp(redirect = 1, filename = ‘filespec’) # will redirect stdout to ‘filespec’
- myapp = MyApp(redirect = 0) #stdio will stay at the console…
Question 23. I Created A Sample Application With Some Controls But When I Reach The Last Control And Hit The Tab Key Again Focus Does Not Return To The First Control. What Is Wrong?
Maybe you are using the wxNotebook window. If you place a wxNotebook directly on a frame tab order usually gets confused. Try placing a wxPanel on the wxFrame and put wxNotebook onto this panel. As a rule, simply do not place wxNotebook directly on a wxFrame (except the frame is a wxDialog?). If you use a
WxDialog, tabbing should work as expected. If you use a MDIChildFrame, you must create a Panel first, and then put your controls on the Panel, not directly on the MDIChildFrame.
Question 24. What Does “unicode Build” Really Mean?
Unicode in Python: There are a few aspects of unicode-ness to keep track of here. First, in Python there are unicode objects and there are string objects. String objects are essentially a sequence of 8-bit characters, and unicode objects are a sequence of “wide” characters (either 16-bit or 32-bit depending on platform and options used when building Python.) They are related to each other in that a unicode object can be encoded into a string object using a specific “codec” (a matched enCODer and DECoder pair). You can think of a codec as being like the “magic decoder ring” that came in the box of cereal when you were a kid, (or perhaps when your dad was a kid…) String objects can be decoded into a unicode object using the decoder part of the codec.
Unicode in wxWidgets: On the other side of the fence is wxWidgets and how it can use unicode. In the C++ code there is a class named wxString, and all string type parameters and return values in the wxWidgets library use a wxString type. The wxWidgets library has a unicode compile switch that makes wxString be either an array of 8-bit characters (the C char data type) or an array of wide characters (C’s wchar_t data type.) So in other words you can have a wxWidgets build where wxStrings are unicode and another build where wxStrings are ansi strings.
Unicode in wxPython: So what does all that mean for wxPython? Since Python does know about string and unicode objects, and you can have both in the same program, the wxPython wrappers need to attempt to do something intelligent based on if the wxWidgets being used is an unicode build or an ansi build.
So, if wxPython is using an ansi build of wxWidgets then:
- Return values from wx functions and methods will be string objects.
- Strings passed as parameters to wx functions and methods will be used without conversion.
- Unicode objects passed as parameters to wx functions and methods will first be converted to a string object using the default encoding. You can use sys.getdefaultencoding() to find out what the default encoding is. You may get an UnicodeEncodeError if there are characters in the unicode object which don’t have a matching ordinal in the default encoding. To work around this you can convert the unicode object to a string yourself using a different codec.
And if wxPython is using an unicode build of wxWidgets then:
- Return values from wx functions and methods will be unicode objects.
- Strings passed as parameters to wx functions and methods will first be converted to a unicode object using the default encoding. You may get an UnicodeDecodeError exception if there are characters in the string that are not mapped to unicode ordinals by the default encoding. To work around this you can convert the string to unicode yourself using a specific codec.
- Unicode objects passed as parameters to wx functions and methods will be used without conversion.
Question 25. What Is A Wxpython Release Series?
The wxWidgets project has adopted the release model used by the Linux Kernel project where there are alternating sets of releases where one set are considered “stable” and the next set are considered “development.” For wxWidgets “stable” and “development” do not refer to bugginess, but to the stability of the API and backwards compatibility.
- Stable: For the duration of the series existing APIs are not modified, although new non-virtual class methods and such can be added. Binary compatibility of the C++ libs is maintained by not allowing any changes that modify the in-memory size or layout of the classes and structs. This can and often does impose limitations on what kinds of enhancements or bug fixes can be performed in a stable release series, however this really only affects the C++ layer because in Python being backwards compatible has a slightly different connotations.
- Development: The main purpose of the development series of releases is to add new functionality or to correct problems that could not be corrected in a stable series because of binary compatibility issues, all in an effort to create the next stable series. So for the duration of the development series existing the APIs are allowed to be modified or removed as needed, although most of the time C++ source-level compatibility is maintained via deprecated overloaded functions or macros, etc. For wxPython this often means that there will be source-level incompatibilities because there is no overloading or macros, and in order to support the new version of the API sometimes the old version has to be removed.
Because of the binary compatibility issues, the latest development version of wxWidgets/wxPython can often be less buggy than the latest version of the last stable release series. However there is the trade-off that the APIs may be changing or evolving between versions in the development series.
Question 26. How Do The Version Numbers Work?
For releases wxPython uses a 4 component version number. While this looks a lot like how version numbers are used in other Open Source projects, there are a few subtle differences. So for some release A.B.C.D you can deduce the following:
1. Release Series: The first two components of the version number (A.B) represent the release series, and if the B component is an even number then it is a stable series, if it is an odd number then it is an development release series. For example, 2.4, 2.6, and 2.8 are stable and the API is more or less frozen within each series, and 2.3, 2.5, and 2.7 are development and the API and functionality is allowed to change or evolve as needed.
Because of this there can be quite large changes between one stable series to the next (say 2.4 to 2.6) and this often throws people off because in other projects changes of that magnitute would have caused the first component of the version number to change. Instead you should think of the combination of A.B as being the major number of the version.
2. Release Number: The third component of the version number (C) represents one of the releases in a release series. For example, 2.5.0, 2.5.1, 2.5.2, 2.5.3… are all releases in the 2.5 release series. (And since in this case it is an development series then the API and functionality of 2.5.3 has evolved to be different in places than it was in 2.5.0.) The C++ wxWidgets releases usually stop here and only A.B.C releases are made.
3. Subrelease number, or wxPython release: The fourth component of the version number (D) is used to represent a subrelease, or incremental releases betweeen the official wxWidgets releases. These releases include fixes for wxWidgets bugs that wxPython may have exposed, or minor enhancements that are important for wxPython. This is not an arbitrary wxWidgets snapshot, but rather a tested version of the code with fixes and enhancements not yet available from wxWidgets except from the source code repository.
It can sometimes be confusing to keep track of the various size-related attributes of a wx.Window, how they relate to each other, and how they interact with sizers. This document will attempt to clear the fog a little, and give some simple explanations of things.
BestSize: The best size of a widget depends on what kind of widget it is, and usually also on the contents of the widget. For example a wx.ListBox’s best size will be calculated based on how many items it has, up to a certain limit, or a wx.Button’s best size will be calculated based on its label size, but normally won’t be smaller than the platform default button size (unless a style flag overrides that). Get the picture? There is a special method in the C++ code called DoGetBestSize() that a class needs to override if it wants to calculate its own best size based on its content. The default DoGetBestSize() is designed for use in container windows, such as wx.Panel, and works something like this:
- if the window has a sizer then it is used to calculate the best size.
- if the window has layout constraints then that is used to calculate the best size.
- if the window has children then the best size is set to be large enough to show all the children.
- if there are no children then the window’s min size will be used for the best size.
- if there is no min size, then the current size is used for the best size.
MinSize: The min size of a widget is a size that is normally explicitly set by the programmer either with the SetMinSize() method or the SetSizeHints() method. Most controls will also set the min size to the size given in the control’s constructor if a non-default value is passed. Top-level windows such as wx.Frame will not allow the user to resize the frame below the min size.
Size: The size of a widget can be explicitly set or fetched with the SetSize() or GetSize() methods. This size value is the size that the widget is currently using on screen and is the way to change the size of something that is not being managed by a sizer.
ClientSize: The client size represents the widget’s area inside of any borders belonging to the widget and is the area that can be drawn upon in a EVT_PAINT event. If a widget doesn’t have a border then its client size is the same as its size.
Initial size: The initial size of a widget is the size given to the constructor of the widget, if any. As mentioned above most controls will also set this size value as the control’s min size. If the size passed to the constructor is the default wx.DefaultSize, or if the size is not fully specified (such as “size=(150,-1)”) then most controls will fill in the size using the best size and will set the initial size of the control to the resulting size.
AdjustedBestSize: This value is calculated by taking the max of the widget’s best size and min size values and returning the result. This has been removed in 2.7.2.
GetEffectiveMinSize: (formerly GetBestFittingSize) A blending of the widget’s min size and best size, giving precedence to the min size. For example, if a widget’s min size is set to (150, -1) and the best size is (80, 22) then the best fitting size is (150, 22). If the minsize is (50, 20) then the best fitting size is (50, 20). This method is what is called by the sizers when determining what the requirements of each item in the sizer is, and is used for calculating the overall minimum needs of the sizer.
SetInitialSize(size): (formerly SetBestFittingSize) This is a little different than the typical size setters. Rather than just setting an “initial size” attribute it actually sets the minsize to the value passed in, blends that value with the best size, and then sets the size of the widget to be the result. So you can consider this method to be a “Smart SetSize”. This method is what is called by the constructor of most controls to set the minsize and initial size of the control.
window.Fit(): The Fit method sets the size of a window to fit around its children. If it has no children then nothing is done, if it does have children then the size of the window is set to the window’s best size.
sizer.Fit(window): This sets the size of the window to be large enough to accommodate the minimum size needed by the sizer, (along with a few other constraints…) If the sizer is the one that is assigned to the window then this should be equivalent to window.Fit().
sizer.Layout(): Recalculates the minimum space needed by each item in the sizer, and then lays out the items within the space currently allotted to the sizer.
window.Layout(): If the window has a sizer then it sets the space given to the sizer to the current size of the window, which results in a call to sizer.Layout(). If the window has layout constraints instead of a sizer then the constraints algorithm is run. The Layout method is what is called by the default EVT_SIZE handler for container windows.
Question 27. Why Can’t I Globally Catch Exceptions From Mainloop?
One of the often asked questions for wxPython has to do with why you can’t use a global exception handler wrapped around the call to the app object’s MainLoop method. To understand the answer to this question you need to keep in mind that wxWidgets and the wxPython wrappers are C++ code and whenever an event handler or other callback is called you end up with another layer of C++ and Python code on the stack. I usually refer to this as the C++/Python sandwich. For example:
- You call MainLoop: this is a Python to C++ transition.
- The user clicks a button and your EVT_BUTTON handler is called, which transitions back to Python
- The handler calls self.SetSize, now we are back in C++
- You have a EVT_SIZE handler that is called, which puts us back in Python
- The handler calls Layout(), back in C++
- The Layout causes some other panel to get resized, and it has it’s own EVT_SIZE handler, now we’re back in Python again.
- That EVT_SIZE handler calls Update to force an immediate repaint of the panel, putting us back in C++
- The handler for the EVT_PAINT is called, which puts control on the Python side once more.
Question 28. Why Doesn’t A Sizer On A Wx.window Work?
probably a little surprising to find out that it doesn’t work at all. No layout happens. It’s as if the sizer isn’t there at all. There is a good reason for this, and there is also a very simple workaround.
The reason is that since wx.Window is the base of the window hierarchy then adding auto-layout support to wx.Window would mean that every widget would inherit it, even those that are not intended to be containers of other windows. For example it doesn’t make much sense to have wx.CheckBox support auto-layout functionality because it will likely never have child widgets that it needs to manage.
The workaround is very simple, just use a wx.Panel instead of a wx.Window. If for some reason you do want to use a wx.Window and also give it a sizer, then simply bind a handler for EVT_SIZE to the window too, and in the event handler call self.Layout().
Perl Scripting Interview Questions
Perl Scripting Tutorial
C++ Interview Questions
PHP Interview Questions
C Interview Questions
Ruby on Rails Interview Questions
Perl Scripting Interview Questions
Ruby Interview Questions
Ruby on Rails Tutorial
Django Interview Questions
C++ Interview Questions
Lisp programming Interview Questions
Ruby on Rails 2.1 Tutorial
R Programming language Interview Questions
PHP Interview Questions
Lisp programming Tutorial
Python Automation Testing Interview Questions
C Interview Questions
R Programming language Tutorial