KDE下采用XML进行界面配置机制
[这段时间在写界面,明白了一点点,所以总结了一下]
根据编译原理中的common subexpression elimination(CSE)原理:如果某几个高层部件都会使用到某个共用的底层部件C,那么可以把C提出来,而不需要在每个部件中都包括一个C,为此可以节省开销。实际上这个原理可以应用于任何具有共用部件的地方,为了可以避免产生冗余。另一个延伸是:一个应用往往有很多高层操作,当对这些高层操作进行更小粒度的划分时,会发现某些高层处理中包括很多共用的操作。为此我们可以通过划分高层操作来把功能进行切割,使之变成更小粒度的操作,并用这些更小粒度的操作来合成高层的各种操作。通过平衡一定的功能粒度并进行分析,我们可以提炼和构造出最小操作集(即这些操作是原子操作,是其它操作所不能替换的),然后仅仅实现这些最小操作集就可以了,为此减轻了实现工作量,避免了大量的冗余,如同可以把所有计算机的操作归结为移动、相加、取负和跳转指令一样。
实际上采用XML来设计菜单、工具条和上下文菜单的原理与如上所述的CSE相似,即把它们三者都共用的部分--Action提出来(使用actioncollection函数,且给每个action一个name,这样XML配置文件中就可以引用这些action了),然后大家使用一个XML文件(appui.rc)来配置各个菜单的各个项中出现哪个Action,工具条按钮中出现哪些Action,上下文菜单中出现哪些Action。当应用程序启动时,它将会读取appui.rc文件,然后根据此文件的配置来加载菜单、工具条和上下文菜单,当加载其它的插件时,这些插件的菜单和工具条也会加载到现有的菜单和工具条中,这与KMainWindow类继承自KXMLGUIClient类有关。当需要改变菜单或工具条的配置时,仅仅需要改变配置文件即可,而不需要改动源代码。配置XML文件的DTD(data type definition)能够在kdeui/kpartgi.dtd文件中找到。为此,当需要进行disable或enable时,就可以仅仅对这个共用的Action实施操作就可以了,免去了对各个引用此操作的菜单、工具条和上下文菜单同时实施,其建立的步骤如下:
(1)在主要类(一般是继承自KMainWindow的类)的宣告中申明建立Action的函数--setupAction,此函数创建标准的应用程序Action和用户自定义的Action,每个Action赋予一个不同的name,且使用actioncollection函数来收集所有的这些函数,类似如下的代码:
class TopLevel : public KmainWindow {
protected:
void setupActions();
};
(2)在topLevel类的构造函数中,需要调用setupAction来创建action,其源代码类似如下:
TopLevel::TopLevel (QWidget *, const char *name)
: KMainWindow ( name) {
setupStatusBar();
setupActions();
readSettings();
}
(3)由于我们没有如传统方式那样创建file、edit等popupmenu,所以我们不需要在构造函数中做任何与菜单、工具条和上下文菜单相关的事情。接下来我们定义setupAction函数,其代码类似如下:
void TopLevel::setupActions() {
// 创建菜单
KStdAction:penNew(this, SLOT(file_new()), actionCollection());
KStdAction:pen(this, SLOT(file_open()), actionCollection());
new KAction(i18n("&Insert File", icon_file, 0, this, SLOT(file_insert()),
actionCollection(), "insert_file"
new KAction(i18n("I&nsert Date", icon_file, 0, this, SLOT(insertDate()),
actionCollection(), "insert_date"
......
createGUI();
}
对于标准的Action,如openfile,new_file,我们使用KStdAction,对于用户自定义Action,我们使用KAction,且我们需要给每个Action指定一个name,这样在XML配置文件中就可以使用这个name来引用各个Action了。且最后一定要调用createGUI()函数,否则不会创建GUI界面,而且你一定要install应用程序。此时,配置菜单、工具条按钮的XML文件会被放置在一个既定的位置,这样应用程序启动时能够根据此文件而加载菜单、工具条等。如果不install,那么它仅仅只有在aetupAction中创建的标准菜单和按钮。
同时我们可以指定一个菜单项目、按钮或上下文菜单的图标(上面的icon_file)。应用程序启动时,可以带很多参数,如界面的风格,显示的主题等等,根据这些参数的不同,界面的显示也有所不同。原来我不知道程序如何加载图标,因为应用程序的安装时的图标中没有我在界面中看到的图标,后来才发现这些图标在/usr/share/icons目录下面。实际上在icons目录下有很多子目录,每个子目录就代表一种显示风格,如Bluecurve、gnome、crystalsvg等等,根据传递给应用程序参数的不同,应用程序将从不同的风格目录下加载不同的图标,详细请参考KDE API Reference中对类kdecore/KIconLoader的说明。
(4)创建了各种Action后,我们就可以使用XML文件来配置菜单、按钮、工具条和上下文菜单的显示,其XML文件配置类似如下:
<!DOCTYPE kpartgui>
<kpartgui name="kedit">
<MenuBar>
<Menu name="file"><text>&File</text>
<Action name="file_open_url"/>
<Action name="save_to_url"/>
</Menu>
<Menu name="edit"><text>&Edit</text>
<Action name="insert_file"/>
<Action name="insert_date"/>
<Action name="clean_spaces"/>
</Menu>
<Menu name="Right_Mouse_Button"><text>R&ight_Mouse_Button</text>
<Action name="file_new" />
<Action name="file_open" />
</Menu>
</MenuBar>
<ToolBar fullWidth="true" name="JixuToolBar">
<Action name="file_open"/>
<Action name="file_close"/>
<Action name="file_new"/>
</ToolBar>
</kpartgui>
在XML文件中,如果要表示&字符,那么需要写作&,加上&字符的作用是为了使此菜单的第一个字符F有一个下划线,且有快捷菜单ALT+F。我们也加入了一个名为Right_Mousr_Button的菜单,这样当我们点击右键时,我们可以通过如下语句来实现上下文菜单:
[1] QPopupMenu *pop = (QPopupMenu *)factory()- >container("Right_Mouse_Button", this)
[2] pop->popup(point)或pop->exec(para或null) // point是鼠标右击处的点
同时,我们还使用<ToolBar>来加入了一个工具条,这样程序运行时将出现此工具条,且在主菜单中会自动出现一个菜单项来控制是否显示此工具条。
(5)最后,我们需要在Makefile.am文件中增加一点语句来使Install过程能安装appui.rc文件到希望的位置,其语句类似如下:
rcdir = $(kde_datadir)/app
rc_DATA = appui.rc
(6)详细的说明请参考tools/gui/kde/document/xmlui目录中的说明(它还说明了如何使用KMainWindow::stateChanged()函数来改变application state,即以群组的方式改变菜单和工具条按钮的状态和RMB[right mouse button])和document目录下的Defining menus and toolbars in XML.html文件说明(还描述了如何提供dynamic menu和context menu)。
Reference
[1] 参考文档
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论