繁体   English   中英

对 ncurses 使用本机 C++ 包装器,如何创建菜单/子菜单系统?

[英]Using native c++ wrappers for ncurses, How can I create a menu/submenu system?

我花了去年学习 C++(使用 C++ Primer 作为来自https://stackoverflow.com/a/388282/1440199的推荐材料)。 我想学习使用 ncurses 来制作我的第一个飞行单人程序。 尽管 NCurses 是基于 C 的,但原生 ncurses C++ 包装器的存在或多或少鲜为人知。 然而,它们的文档几乎不存在; 有一个 demo.cc 文件我一直在使用作为基础,以及网络上的一些地方 无论如何,我已经把它作为我的期末考试,可以这么说,理解和使用这些包装器。

我遇到的问题属于“最佳编程实践”类型:由于缺少文档化示例,我不确定从演示的初始菜单系统创建子菜单的最佳方法。

我能想到的最好的主意是使用示例方式将 ncurses++ 的 NCursesUserItem 附加到菜单项 用户指针是指向上一个菜单类的指针吗? 在 NCurses 中,您可以发布和取消发布菜单,所以我还假设我想在新菜单“发布”时“取消发布”上一个菜单,这就是为什么我想要在显示新菜单时指向上一个菜单的原因。

将用户数据(对于 set_item_userptr)附加到菜单项的类型安全示例方法:

template<class T> class SubMenu : public NCursesUserItem<T>
{
  public:
    SubMenu (const char* p_name,
             const T* p_UserData)
            : NCursesUserItem<T>(p_name, static_cast<const char*>(0), p_UserData){}

    virtual ~SubMenu() {}

    bool action() {
        // I believe I want to unpost the previous menu here
        //  before posting the new submenu?
        NCursesUserItem<T>::UserData()->prev_menu()->unpost();
        //This doesn't work, but its kind of what I want to do.
        NCursesUserItem<T>::UserData()->post();
        return FALSE;
    }
};

主菜单对象。 我在这里创建了子菜单对象并将“this”(主菜单指针)作为参数传递给它。

class MainMenu : public NCursesMenu
{
  private:
    NCursesMenuItem** I;
    Choice0Menu* u;
#define n_items 3
  public:
    MainMenu ()
    : NCursesMenu (n_items+2, 25, (lines()-5)/2, (cols()-23)/2), I(0), u(0)
    {
        u = new Choice0Menu(this);
        I = new NCursesMenuItem*[1+n_items];
        I[0] = new SubMenu<Choice0Menu> ("Choice 0", u);
        I[1] = new PadAction("Choice 1");
        I[2] = new QuitItem();
        I[3] = new NCursesMenuItem();

        InitMenu(I, TRUE, TRUE);
    }
};

Choice0Menu 类,它应该包含一个返回主菜单的返回按钮 (I[2])

class Choice0Menu : public NCursesMenu
{
  private:
    NCursesMenuItem** I;
    MainMenu* w;
#define n_items 3

  public:
    Choice0Menu (MainMenu* prev)
    : NCursesMenu (n_items+2, 25, (lines()-5)/2, (cols()-23)/2), I(0), w(prev)
{
    I = new NCursesMenuItem*[1+n_items];
    I[0] = new ScanAction("Submenu Choice 0");
    I[1] = new PadAction("Submenu Choice 1");
    I[2] = new MainMenuAction("Go Back");
    I[3] = new NCursesMenuItem();

    InitMenu(I, TRUE, TRUE);

    // returns the pointer to the prev object
    MainMenu* prev_menu() const{
        return w;
    }
};

我只是对这种做法有很多疑问,例如,也许我在创建子菜单时不必将整个“this”指针传递给主菜单,只需传递和取消发布成员即可。 并且 MainMenu 和 Choice0Menu 类在功能上非常相似,所以甚至可以将其合并为一个模板类? 由于 Choice0Menu 将 MainMenu 作为参数,因此采用任何菜单类型都应该是 T* ..

我的方法似乎不是解决问题的“干净”方法。

谢谢您的帮助。 我一直在研究这个问题近 2 周了...

老实说,我不会使用本机 C++ 接口。 我也进入了 ncurses 并看到了本机 C++ 接口,但它只是一个愚蠢的包装器。 没有类型检查,全部使用原始指针(没有 std::shared_ptr 系统),它比 Windows 中的 ATL 更糟糕。

老实说,我只是继续重建其中的一些类,因为这些类本身是非常松散的包装器。 我很喜欢他们试图摆脱所有宏并将它们更改为内联函数的方式,但是没有某种指针管理,甚至只是使用 string_view,这真的没有意义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM