WxFAQ

From WxWiki
Jump to navigation Jump to search

This is a user maintained FAQ, the purpose of which is to allow easy augmentation of questions and answers to build up a large knowledge base on wxWidgets. If you don't find your question or the answer to your question doesn't give enough details, check the Official wxWidgets FAQ as well as the FAQs maintained on the wxWidgets Forums (don't miss the exhaustive C++ Users Forum FAQ or Paul's wxWidgets Newbie FAQ).

Why are backgrounds of windows ugly, dark grey on Windows? I want them like my dialog boxes.

This is the default background colour for frames on Microsoft Windows. You can get the familiar light-grey background by putting a wxPanel on the frame first, and putting all your other controls on this wxPanel. If the wxPanel is the only child window of the frame then it will automatically take up the entire client area of the frame.

wxBoxSizer* topSizer = new wxBoxSizer( wxEXPAND );
wxPanel *panel = new wxPanel(this, wxID_ANY, 
                             wxDefaultPosition, 
                             wxDefaultSize,
                             wxTAB_TRAVERSAL,
                             _("mypanel"));
panel->SetSizer(topSizer);
wxButton *ok_button = new wxButton( panel, wxID_OK );
wxButton *cancel_button = new wxButton( panel, wxID_CANCEL );
topSizer->Add(ok_button);
topSizer->Add(cancel_button);

See wxPanel in the documentation for more information on panels.

Objects I put in sizers are not expanding like I want them to

wxWidgets sizers are quite powerful but understanding how they work can be a little confusing at first. In addition to sizer tutorials and documentation around, here is the golden tip :

There are two different ways to make a widget expand when calling wxSizer::Add

  • The first is the proportion integer parameter
    • this flag acts in the "main" direction of the sizer. For instance, in a vertical sizer, the proportion dictates vertical grow, whereas in a horizontal sizer the proportion flag dictates the horizontal growth.
    • A proportion of "0" means "stick to the minimum size in this direction", while a proportion > 0 makes the widget grow (and a widget with proportion "2" will be twice as big as a widget with proportion "1")
  • The second is the wxEXPAND style flag.
    • This flag basically causes the widget to expand in the direction(s) not covered by the proportion flag mentioned just above. For instance, in a horizontal sizer, the wxEXPAND flag makes the widget expand vertically (if there is room), whereas in a vertical sizer it makes the widget expand horizontally.
    • It's important to note that this flag will only make the widget expand within its parent; so also make sure the parent container is large enough and/or expands too, as setting the wxEXPAND flag on a widget that is placed e.g. inside a small panel may not cause much visible effect since the widget won't expand beyond its parent panel.

Why does my app take a Windows-95-like look on Windows ?

This question is asked very frequently, do a quick search for 'manifest'. This is a Windows issue, not a wxWidgets issue.

A quick search on the forum gave these :

Also see this official readme from the wxWidgets source tree : http://svn.wxwidgets.org/viewvc/wx/wxWidgets/trunk/docs/msw/winxp.txt?revision=61354&view=markup

How can I convert a wxString to <insert type here>?

See Converting everything to and from wxString

How can I convert a <insert type here> to wxString?

See Converting everything to and from wxString

Why do I get weird issues when modifying GUI controls from a thread?

wxWidgets (like most GUI toolkits underneath it) is not thread-safe, and handling of GUI components should always be done exclusively in the main thread. So your threads must not edit the GUI controls directly, but post an event to the main thread and let it do it : Inter-Thread_and_Inter-Process_communication#Sending_custom_events_to_the_main_thread

Note that, although ::wxMutexGuiEnter and ::wxMutexGuiLeave exist, they are more a hack than a desirable solution, and will not work in every situation; so event passing between thread remains the correct way to go.

XPM images don't display the 'silver' colour correctly

In wxWidgets XPM, "silver" is not defined as a color. This "silver" will be generated by a lot of external tools that output XPM. You will need to replace it manually in the XPM file with the hex number C6C6C6.

Why is the IMPLEMENT_APP macro used to generate the entry point? Can't I just declare a "main" function?

Actually, nothing prevents you from declaring a main function yourself if you do not wish to use the macros. The reason the IMPLEMENT_APP macro exists is simply because not all platforms use "main"; as a notable example, Windows uses "WinMain" instead. So the macro is there to save you from the need to write different mains for different platforms.

Why do I get the linker error "undefined reference to `MyFrame virtual table'"?

Probably you do DECLARE_EVENT_TABLE() for MyFrame, but you don't create an event table.

This can actually happen in any case where virtual methods are declared but not defined. This can sometimes happen in roundabout ways, e.g., if you are inheriting from a class with a virtual destructor, but you haven't defined a virtual destructor for your class. You can find more information about this in the GCC FAQ.

One last possible cause is having a #pragma interface without a matching #pragma implementation.

How can I access argc/argv (command-line arguments passed to my application) ?

See these manual pages :

Under Linux, upon running my application, why do I get the error message "error while loading shared libraries: libwx_gtk-x.x.so"?

This message means that the library is not in the system search path for shared libraries. Usually this means either:

  • You forgot to run ldconfig after running make install to install wxWidgets (using Linux).

On some linux running ldconfig isn't enought because you have to add this line to your /etc/ld.so.conf file:

/usr/local/lib

Once it's added, run ldconfig as root.

  • make install installed the shared library in a directory (usually /usr/local/lib) not scanned by ldconfig on your system.

To resolve this issue, you can set the LD_LIBRARY_PATH environment variable to include the directory containing the shared library. Alternatively, add this directory to your /etc/ld.so.conf file, and re-run ldconfig.

A related question :

./wxbasic: error while loading shared libraries:
../../lib/libwx_gtk-2.3.so.0.0.0: cannot open shared object file:
No such directory

This is a classic problem and I have to say that for once, it's simpler on Windows.

Whereas Windows has a single PATH with both .exe and .dll, Unix is different. Usually the executable is on PATH and shared libraries are on LD_LIBRARY_PATH or something like that. I think that answers part of your question about how things are organized, but alas it's not relevant to this problem.

This particular user is having problems, I think, because of the way you linked wxBasic. I bet you linked

../../lib/libwx_gtk-2.3.so.0.0.0

into your executable and not something like

-L../../lib -lwx_gtk-2.3

When you used that relative path (or even a full path), the path to the shared library is copied into the executable. When the executable is run, it expects to find the shared library in ../../lib, not in one of the "standard places" like /usr/lib.

So what we usually do is use the -L and -l options to the C++ compiler/linker. The -L says WHERE to look for libraries and the -l suggests what the library is called. I say "suggests" because the libabc.so (or libabc.a) is refered to with -labc. Also, the version number stuff at the end is somehow ignored with the -l in a way I don't understand.

Why does my control take up the whole frame even though I give it an explicit size?

If you only have one window in a frame, that window will automatically take the whole space. If you really want only one window that doesn't take the whole space, try adding a second, blank wxWindow to the frame.

Under normal circumstances, however, the only child of your frame should be a wxPanel, and any other controls should be descendents of that panel. Having a panel present in this manner can solve a number of unexpected behaviors including incorrect colors, missing events, and improper sizer behavior.

My application does not exit

A wx app doesn't close until the last top-level window (frame, dialog, wizard or taskbaricon) is destroyed.

When you close a wxFrame, it destroys itself. When you close a wxDialog, it just hides, so you need explicitly to destroy dialogs yourself later (or, for modal dialogs, create them on the stack; then they die when they lose scope). Terminate modal dialogs with EndModal(), not close, if you close them yourself.

If can't keep track of what toplevel windows are open, just calling wxGetApp().ExitMainLoop() should terminate the application gracefully in any case

Also check that all threads have been terminated, if you created threads besides the main one

(credits for explanation : David Hart and Doublemax)

Why does my application crash on exit?

Chances are you are freeing something that was already freed (see Avoiding Memory Leaks).

If you are using SuSE 8.2, you are using a buggy non-release version of gcc, which causes the crashing. SuSE 10.2 also had some wrongly-configured WxWidgets rpm packages available from Packman-Bremen that crashed on exit.

Why isn't wxString( wxT("(non iso8859-1 chars)") ) displayed correctly and why can't it be converted back to the initial encoding?

Because the input charset of a cpp compiler is 7bit-ascii. Chars >0x7f are considered iso8859-1. It is these iso8859-1 chars that are encoded to unicode and not the ones of your native language. Do not use wchar_t string literals. Use wxString( "(non iso8859-1 chars)", wxConvLibc ) instead.

Another option is to configure your compiler to accept Unicode encoded files.

Why won't my Mac application take focus?

You need to set up the resources to operate in the Mac windowing environment by creating a bundle. For details, see WxMac_Issues.

If you're using python, newer versions have the resources set up correctly by default. However, in older versions you will need to use pythonw as the interpreter instead of python.

What's the difference between a wxFrame and a wxWindow?

A wxFrame is a top-level window, normally referred to as windows in interfaces. A wxWindow is a generic class for any drawable object on the screen. Under normal circumstances, you create a frame, place a panel in the frame, then place other wxWindow subclasses (wxButton, wxTextCtrl, etc.) in the panel.

What's the difference between a wxFrame and a wxDialog?

A frame is what you normally think of as a window; it's used for the primary application display or documents or other long-running views. A dialog is for short term interactions to query the user for specific information.

From the end user perspective, some platforms might render dialogs differently, e.g. with different decorations. From the programmer perspective, dialogs can (more easily) be modal, and don't delete themselves on close so that you can retrieve the information from them after close.

If you were writing a web browser in wxWidgets, the browser window would be a frame and the preferences dialog would be a dialog.

If you were writing a word processor in wxWidgets, the document would be a frame and the font dialog would be a dialog.

If you're tempted to put an "OK" button on a top level window, it's probably a dialog. If you're tempted to use a menu with a top level window, it's probably a frame.

Why does trying to load images fail / show an error window?

Call this first :

wxInitAllImageHandlers()


Why does my app crash in the callback of an event bound with Connect() ?

Most likely you passed the wrong event sink parameter (or omitted it) while calling ->Connect(...); By default wx expects the event callback to be in the object you connect. If your callback is not in the very object you connected, you need to pass an event sink parameter.

See docs for wxEvtHandler.

Note that as of wxWidgets 2.9/3.0, use Bind instead of Connect, since Bind will give you a compile-time error if you do this mistake.

How can I make plots or charts with wxWidgets?

One way is to manually draw them on a panel (http://wiki.wxwidgets.org/Drawing_on_a_panel_with_a_DC)

However, several people already went through that and provided various add-ons you can try :

How can I create diagrams with connected nodes?

A not very good idea is to create a wxPanel for each node and then move the panels around with drag and drop (wxWidgets does not support overlapping components, and besides this will get very slow when you have a lot of nodes)

One way is to manually draw them on a panel (http://wiki.wxwidgets.org/Drawing_on_a_panel_with_a_DC)

However, several people already went through that and provided various add-ons you can try :