[wxWidgets] 1. 安装及"hello world"程序

时间:2022-04-05 06:44:40

关于wxWidgets的优越已经在它的官方网站有所阐述,本文不再赘述。 本系列主要记录学习这个软件包过程中遇到的问题以及心得。

1.  安装

从源码安装虽然大多时候不是一件轻松的过程,但是基于以下两个优点作者选择从源码安装。(顺便提一句如果是Linux的新手,首要的选择还是看看正在使用的发行版本所提供的package管理工具,诸如apt 、yast等)

  • 在解决各种依赖关系的时候能够认识不少接受程度比较高的库
  • 好奇的时候可以潜入到源码中去看看究竟。

1.1 下载源码

源码下载地址,点这里。我选择的版本是2.8.12,大概18M左右的样子。

1.2 编译安装

解压以后,在wxWidgets-2.8.12的目录下名如 readme-<plat_form>.txt 以及 install-<plat_form>.txt的文件需要大概浏览一下。其中阐述了在各种平台下安装需要做的步骤。wxWidgets官方声称支持目前为止的所有desktop的GUI环境,在这里的确可以看到针对ms windows、x11、max、motif、gtk等都有所支持。

作者所使用的环境为Ubuntu 13.04 + gnome,因此选择gtk包。 尽管安装过程在install-gtk.txt叙述已经很完备,但还是在这里记录一下我的编译过程吧:

  • mkdir build_gtk;创建一个新的目录用于存放编译产生的object文件,以及库文件。不这样做得话其实也行得通,只是当前目录会被编译产生的中间文件占据,影响阅读。
  • cd build_gtk; ../configure --with-gtk --prefix=/usr
  • make ;编译过程不算很长,大概10+分钟的样子
  • sudo make install;注意,我在configure的时候所使用的prefix是‘/usr’,这样做得目的是:安装以后的头文件以及库文件分别在'/usr/include'以及'/usr/lib'下。以后在使用的时候不用再配置编译器、连接器(这是懒省事的做法)。需要注意的是,实际的安装路径使用了版本号,所以为了在程序中形如“#incude <wx/window.h>"能够奏效,最好手工在‘/usr/include'目录下加一个链接'wx'指向‘/usr/include/wx-2.8/wx'。configure默认的安装前缀(即 --prefix选项)是/usr/local,这样安装以后的头文件以及库文件会在'/usr/local/include'以及'/usr/local/lib'下。这样有助于将系统使用的库和用户使用的库分离,但是使用这些库进行开发的时候需要对编译器进行额外的配置。

作者到此为止RP还不错,在进行编译、安装的过程中没有遇到什么问题(^_^),读者如果遇到问题欢迎留言讨论。不过,需要注意的是,在configure的这一步,留意一下最后的结果,如果最后编译出问题的话大部分情况在编译结果里都会留下一点线索。

注意下面结果中的几个'no', 尤其是11行以后那些。它们表明了我以后如果使用这个安装进行数据库或者游戏开发的时候要遇到问题。(odbc,看起来是一个数据库的接口,sdl在编译各种游戏、多媒体的时候常见一些,至于libmspack是什么在google之前我也不知道。)

 Configured wxWidgets 2.8. for `x86_64-unknown-linux-gnu'

   Which GUI toolkit should wxWidgets use?                 GTK+
Should wxWidgets be compiled into single library? no
Should wxWidgets be compiled in debug mode? no
Should wxWidgets be linked as a shared library? yes
Should wxWidgets be compiled in Unicode mode? no
What level of wxWidgets compatibility should be enabled?
wxWidgets 2.4 no
wxWidgets 2.6 yes
Which libraries should wxWidgets use?
jpeg sys
png sys
regex sys
tiff builtin
zlib sys
odbc no
expat sys
libmspack no
sdl no

2. Hello world 程序

如同V形手虽然俗气但仍然频发现于各个层次的照片中一样,“hello world”虽然毫无新意但仍然不失作为一个demo的合理性。以下的程序来源于wxWidget官网,点这里进行阅读。作者在编译过程中进行了小部分修改(下文假设这段程序被保存为helloWorld.cpp)。

 #include <wx/wxprec.h> 

 #ifndef WX_PRECOMP
#include <wx/wx.h>
#endif class MyApp: public wxApp
{
public:
virtual bool OnInit();
}; class MyFrame: public wxFrame
{
public:
MyFrame( const wxString& title, const wxPoint& pos,
const wxSize& size );
private:
void OnHello( wxCommandEvent& event );
void OnExit( wxCommandEvent& event );
void OnAbout( wxCommandEvent& event ); DECLARE_EVENT_TABLE( );
}; enum
{
ID_Hello =
}; BEGIN_EVENT_TABLE( MyFrame, wxFrame )
EVT_MENU( ID_Hello, MyFrame::OnHello )
EVT_MENU( wxID_EXIT, MyFrame::OnExit )
EVT_MENU( wxID_ABOUT, MyFrame::OnAbout )
END_EVENT_TABLE() IMPLEMENT_APP( MyApp ) bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame("Hello World", wxPoint( , ), wxSize( , ) );
frame->Show( true );
return true;
} MyFrame::MyFrame( const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame( NULL, wxID_ANY, title, pos, size )
{
wxMenu *menuFile = new wxMenu;
menuFile->Append( ID_Hello, "&Hello...\tCtrl-H",
"Help string shown in status bar for this menu item");
menuFile->AppendSeparator( );
menuFile->Append( wxID_EXIT ); wxMenu *menuHelp = new wxMenu;
menuHelp->Append( wxID_ABOUT); wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( menuFile, "&File" );
menuBar->Append( menuHelp, "&Help" ); SetMenuBar( menuBar ); CreateStatusBar( );
SetStatusText( "Welcome to wxWidgets!" ); } void MyFrame::OnExit( wxCommandEvent & event )
{
close( true );
} void MyFrame::OnAbout( wxCommandEvent& event )
{
wxMessageBox(" Ths is a wxWidgets' Hello world sample",
"About Hello World", wxOK|wxICON_INFORMATION );
} void MyFrame::OnHello( wxCommandEvent& event )
{
wxLogMessage( "Hello world from wxWidgets!" );
}

2.1 编译

客观地说,这一个程序其实不太适合作为wxWidgets的见面礼,它比想象中复杂一些,毕竟经典的hello world连与编译指令算到一起也不过5行。(果然,不出所料)编译的时候遇到了一些问题。

作者在实践这个程序之前没有一点使用wxWidgets的经验,所以就先进行了简单粗暴的尝试:gcc helloWorld.cpp 然后就是第一个error找不到setup.h, 确实在/usr/inlcude/wx中并没有这个文件的踪迹。这时候真正的问题是编译方法不对,wxWidgets为了跨平台需要对编译器选项(-I -L)进行一些设置。并且它提供了一个看起来还算比较优雅的解决方案——wx-config。wx-config可以查询当前平台的信息,并且返回编译器所需要的选项(下面的代码给出了wx-config这个工具的帮助信息,以及我们需要的编译选项),我们这里需要的是 --cxxflags。其实这里我们需要的是‘--cppflags’,但是如果不加‘--libs’的话,就会遇到第二个error:wxApp声明(具体是说第一个“{",也就是在上面代码的第8行之前需要一个什么乱七八糟的东西)。正确的编译指令是“ g++ helloWorld.cpp `wx-config  --cxxflags --libs` ”。(Linux新手请留意:wx-config左上边、lib右上边的那俩货不是单引号,而是获取程序标准输出的操作符,对一般的键盘而言在数字键1的左边,即这个符号“~”不加shift)。

 %>build_gtk$ wx-config 

  wx-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--release] [--version-full]
[--list] [--selected-config] [--host=HOST] [--toolkit=TOOLKIT]
[--universal[=yes|no]] [--unicode[=yes|no]] [--debug[=yes|no]]
[--static[=yes|no]] [--version[=VERSION]] [--basename] [--cc]
[--cppflags] [--cflags] [--cxxflags] [--rescomp] [--libs] [--cxx]
[--ld] [--linkdeps] [--utility=UTIL] [LIB ...] wx-config returns information about the wxWidgets libraries available on
your system. It may be used to retrieve the information required to build
applications using these libraries using --cppflags, --cflags, --cxxflags
and --libs options. And you may query the properties of this configuration
using --query-{host,toolkit,widgetset,chartype,debugtype,version,linkage}. If multiple builds of wxWidgets are available, you can use the options
--prefix, --host, --toolkit, --unicode, --debug, --static, --universal and
--version to select from them. The --selected-config option shows the name
of the current configuration and --list shows available alternatives which
match specified criteria. The --utility option returns the correct version
of UTIL to use with the selected build. The --linkdeps option returns only
static libraries for your makefile link rule dependencies. Optional LIB arguments (comma or space separated) may be used to specify
the wxWidgets libraries that you wish to use. The magic "std" label may
be used to import all libraries that would be used by default if none were
specified explicitly, e.g. wx-config --libs core,base. %> wx-config --cxxflags --libs
-I/usr/lib/wx/include/gtk2-ansi-release-2.8 -I/usr/include/wx-2.8 -D_FILE_OFFSET_BITS= -D_LARGE_FILES -D__WXGTK__ -pthread
-pthread -lwx_gtk2_richtext-2.8 -lwx_gtk2_aui-2.8 -lwx_gtk2_xrc-2.8 -lwx_gtk2_qa-2.8 -lwx_gtk2_html-2.8 -lwx_gtk2_adv-2.8 -lwx_gtk2_core-2.8 -lwx_base_xml-2.8 -lwx_base_net-2.8 -lwx_base-2.8

作者遇到的第三个error可能跟版本有关,官网给出的这个helloWorld程序我在对着敲了一遍以后(居然用尽了今天的RP),是无法编译通过的。具体的第三个error是几个事件有关的宏定义上。具体在23、31、35、37行,原文给出的几个宏都是以wx开头的,在2.8版本中去掉这些wx的开头就对了。有可能在源码中搜索一下或者去manual里面搜索一下就可以很快地找到答案。但是作者在排除这个问题的时候竟费了一些周折-_-!)

2.2 运行结果

如下所示,很简陋。不过看在几个菜单都能正常运行的份上,花两三个小时也不是很懊恼。

[wxWidgets] 1. 安装及"hello world"程序

3. 参考资料

【1】www.wxwidgets.org


作者通信地址:Boyue.K.Cheung@outlook.com

欢迎交流、指错、提出改进建议。Please feel free to raise any questions, advices. I'll feel free to ignore them if necessary. ~_~