【问题标题】:How do I make a GUI?如何制作图形用户界面?
【发布时间】:2010-09-05 16:03:22
【问题描述】:

我已经为 Nintendo DS 制作了 GUI 系统的许多不同的独立部分,例如按钮、文本框和选择框,但我需要一种将这些类包含在一个 Gui 类中的方法,以便我可以将所有内容绘制到一次全屏,并一次检查所有按钮以检查是否有任何按钮被按下。我的问题是将所有类(例如按钮和文本框)组织到一个 GUI 类中的最佳方法是什么?

这是我想到的一种方法,但似乎不对:

编辑:我使用的是 C++。

class Gui {
    public:
        void update_all();
        void draw_all() const;
        int add_button(Button *button); // Returns button id
        void remove_button(int button_id);
    private:
        Button *buttons[10];
        int num_buttons;
}

这段代码有一些问题,但我只是想告诉你我想要什么。

【问题讨论】:

  • 您可能需要考虑针对该特定平台使用immediate mode GUI 技术。
  • 请修正您的标题,使其更具体。这听起来像是一个“帮助吸血鬼”的问题(“我如何建立一个论坛?”),即使您阅读了这个问题,它也更具体一些。

标签: c++ user-interface


【解决方案1】:

要记住的一个有用策略可能是composite pattern。在较低级别,它可能允许您在构建后更轻松地处理所有 GUI 对象(和对象集合)。但我不知道 GUI 框架设计涉及什么,因此可以在现有项目的源代码中找到一般灵感。 WxWidgets 是一个提供源代码的跨平台 GUI 框架。祝你的项目好运!

【讨论】:

    【解决方案2】:

    我认为看看其他 GUI 工具包的做法将是一个很好的起点。对于 C++ 示例,我听到了很多关于 Qt 的好消息。不过我个人没有用过。当然还有 Nick 提到的 WxWidgets。

    【讨论】:

    • 他就如何为 Nintendo ds 制作 GUI 库寻求帮助。我不认为qt和wxwidget可以支持ds这样的控制台?
    【解决方案3】:

    这个问题与我要发布的问题非常相似,只是我的问题是针对索尼 PSP 编程的。

    一直在玩弄一些东西,查阅了一些书和VTMs,到目前为止这是一个简单的ui系统的粗略想法。

    class uiElement()
    {
        ...
        virtual void Update() = 0;
        virtual void Draw() = 0;
        ...
    }
    
    class uiButton() public : uiElement
    {
        ...
        virtual void Update();
        virtual void Draw();
        ...
    }
    
    class uiTextbox() public : uiElement
    {
        ...
        virtual void Update();
        virtual void Draw();
        ...
    }
    
    ... // Other ui Elements
    
    class uiWindow()
    {
        ...
        void Update();
        void Draw();
    
        void AddElement(uiElement *Element);
        void RemoveElement(uiElement *Element);
    
        std::list <uiElement*> Elements;
    
        ...
    }
    
    void uiWindow::Update()
    {
        ...
        for (list <uiElement*>::iterator it = Elements.begin(); it != Elements.end(); it++ )
            it->Update();
        ...
    }
    
    void uiWindow::Draw()
    {
        ...
        for (list <uiElement*>::iterator it = Elements.begin(); it != Elements.end(); it++ )
            it->Draw();
        ...
    }
    

    原理是创建一个窗口并为其添加ui元素,并从各自的main函数中调用draw和update方法。

    我还没有任何工作,因为我的绘图代码有问题。在 PC 和 PSP 上使用不同的 API,我正在查看一些 OpenGL 和 psp gu 的包装器代码。

    希望这会有所帮助。

    thing2k

    【讨论】:

      【解决方案4】:

      我已经按照您的建议编写了一个非常简单的 GUI。我让它在 Windows、Linux 和 Macintosh 上运行。它也应该相对容易地移植到任何系统,如 PSP 或 DS。

      它是开源的,LGPL 并且在这里:

      http://code.google.com/p/kgui/

      【讨论】:

        【解决方案5】:

        对于任何感兴趣的人,这是我的开源、BSD 许可的 DS GUI 工具包:

        http://www.sourceforge.net/projects/woopsi

        thing2k 的回答非常好,但我强烈建议在基本 uiElement 类中包含子 UI 元素的代码。这是我在 Woopsi 中遵循的模式。

        如果您不在基类中支持此功能,那么当您尝试实现比文本框和按钮更复杂的任何东西时,您将遇到重大问题。例如:

        • 可以将选项卡栏建模为多个按钮,这些按钮组合在一起形成一个强制互斥选择的父 UI 元素;
        • 单选按钮组(同上);
        • 滚动条可以表示为滑块/间距元素和向上/向下按钮;
        • 滚动列表可以表示为一个容器和多个选项 UI 元素。

        另外,值得记住的是,DS 有一个 66MHz 的 CPU 和 4MB 的 RAM,用于存储和执行程序(DS ROM 在运行之前被加载到 RAM 中)。你真的应该把它当作一个嵌入式系统,这意味着 STL 已经过时了。我从 Woopsi 中删除了 STL,并设法节省了 0.5MB。以桌面标准衡量并不多,但这是 STL 垃圾消耗的 DS 总可用内存的 1/8。

        我已经在我的博客上详细介绍了编写 UI 的整个过程:

        http://ant.simianzombie.com/blog

        它包含了我想出的用于重绘屏幕的两种算法的描述,这是创建 GUI 最棘手的部分(一个只是将矩形拆分并记住可见区域;另一个使用 BSP 树,这更有效并且更容易理解)、优化技巧等。

        【讨论】:

        • 是的,我听说过 Woopsi,我会仔细研究一下。也感谢你的博客链接,它看起来很有趣:)
        猜你喜欢
        • 2016-01-30
        • 2022-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-05
        • 2016-06-18
        • 2013-01-23
        相关资源
        最近更新 更多