主程序main.cpp放在src目录下 ,内容很简单:
#include <gtkmm.h>
#include "views/sample_window.h"
int
main(int argc, char *argv[]) {
Gtk::Main kit(argc, argv);
SampleWindow main_window;
Gtk::Main::run(main_window);
return 0;
}
主界面的设计应该比较通用,这里从上到下依次位菜单栏,工具栏,用户区以及状态栏。其中用户区就是一个HBox,方便将来根据需要来设计。
主界面用类SampleWindow来实现,它负责界面的显示以及事件的接受以及处理。这里有个需要注意原则就是事件的处理应该在100ms内完成,以确保良好的用户操作体验。如果需要用耗时的任务,就要使用多线程的方式来实现,这部分内容将在后续文章中进行介绍。目前只需要确保菜单事件以及工具事件得到正确的处理即可。SampleWindow类的源文件放到src目录下views子目录下,将来包括用户自定义的控件的源文件也会放到该目录下。
界面的实现关键就是Gtk::UIManager类的使用,通过res目录下的sample_ui.xml描述文件加入Gtk::UIManager对象,然后添加相应的Action来实现界面的管理。sample_ui.xml文件如下:
<!--
* ui.xml
-->
<ui>
<menubar name="MenuBar">
<menu name="FileMenu" action="File">
<menuitem name="FileNewMenu" action="FileNew"/>
<menuitem name="FileOpenMenu" action="FileOpen"/>
<placeholder name="FileOps_2"/>
<separator/>
<menuitem name="FileSaveMenu" action="FileSave"/>
<menuitem name="FileSaveAsMenu" action="FileSaveAs"/>
<separator/>
<menuitem name="FileQuitMenu" action="FileQuit"/>
</menu>
<menu name="EditMenu" action="Edit">
<menuitem name="EditUndoMenu" action="EditUndo"/>
<menuitem name="EditRedoMenu" action="EditRedo"/>
<separator/>
<menuitem name="EditCutMenu" action="EditCut"/>
<menuitem name="EditCopyMenu" action="EditCopy"/>
<menuitem name="EditPasteMenu" action="EditPaste"/>
<menuitem name="EditDeleteMenu" action="EditDelete"/>
<separator/>
<menuitem name="EditSelectAllMenu" action="EditSelectAll"/>
<separator/>
<menuitem name="EditPreferencesMenu" action="EditPreferences"/>
</menu>
<menu name="ViewMenu" action="View">
<menuitem name="ViewToolbarMenu" action="ViewToolbar"/>
<menuitem name="ViewStatusbarMenu" action="ViewStatusbar"/>
<separator/>
<menuitem name="ViewFullscreenMenu" action="ViewFullscreen"/>
<separator/>
</menu>
<menu name="HelpMenu" action="Help">
<menuitem name="HelpAboutMenu" action="HelpAbout"/>
</menu>
</menubar>
<toolbar name="ToolBar">
<toolitem action="FileNew"/>
<toolitem action="FileSave"/>
<separator/>
<toolitem action="EditUndo"/>
<toolitem action="EditRedo"/>
<separator/>
<toolitem action="EditCut"/>
<toolitem action="EditCopy"/>
<toolitem action="EditPaste"/>
<separator/>
</toolbar>
<toolbar name="FullscreenToolBar">
<toolitem action="FileNew"/>
<toolitem action="FileSave"/>
<separator/>
<toolitem action="EditUndo"/>
<toolitem action="EditRedo"/>
<separator/>
<toolitem action="EditCut"/>
<toolitem action="EditCopy"/>
<toolitem action="EditPaste"/>
<separator expand="true" />
<toolitem action="LeaveFullscreen"/>
</toolbar>
</ui>
具体的实现可以参见源代码,这里简单说一下用法。
/*创建UIManager*/
m_refUIManager = Gtk::UIManager::create();
add_accel_group(m_refUIManager->get_accel_group());
...
/*初始化ActionsGroup并将其加入UIManager*/
m_refSensitiveActionGroup->add(Gtk::Action::create("File", "_File"));
m_refSensitiveActionGroup->add(Gtk::Action::create("Edit", "_Edit"));
m_refSensitiveActionGroup->add(Gtk::Action::create("View", "_View"));
m_refSensitiveActionGroup->add(Gtk::Action::create("Help", "_Help"));
/* 添加action 注意信号同时连接上*/
m_refSensitiveActionGroup->add(
Gtk::Action::create("FileNew", Gtk::Stock::NEW, "_New", "Create a new document"),
Gtk::AccelKey("<control>N"),
sigc::mem_fun(*this, &SampleWindow::onFileNew));
...
/*将xml文件描述的内容加入*/
m_refUIManager->add_ui_from_file(SAMPLE_UI_FILE);
/*根据需要链接proxy信号*/
m_refUIManager->signal_connect_proxy().connect(sigc::mem_fun(*this, &SampleWindow::onConnectProxy));