KDE下采用XML进行界面配置机制

发布于 2022-07-25 11:32:58 字数 7810 浏览 15 评论 0

[这段时间在写界面,明白了一点点,所以总结了一下]

        根据编译原理中的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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文