【问题标题】:How do I show the help strings for wxWidgets popup menus?如何显示 wxWidgets 弹出菜单的帮助字符串?
【发布时间】:2011-04-25 21:25:21
【问题描述】:

wxWidgets 应用程序在主窗口的状态栏中显示普通菜单项的帮助字符串。不幸的是,它似乎没有为使用wxWindow::PopupMenu 命令调用的菜单显示它们,我需要它。

我尝试将EVT_MENU_HIGHLIGHT_ALL 处理程序添加到父窗口,但没有被调用。

必须有某种方法来处理或重定向消息以显示帮助文本。我错过了什么?

【问题讨论】:

    标签: wxwidgets


    【解决方案1】:

    我尝试通过wxFrame 而不是当前窗口(@98​​7654322@)调用它。这有帮助,但作用不大:当鼠标移到弹出菜单项上时,它会清除状态栏,但不会显示它的帮助文本。

    当我深入研究 wxWidgets 源代码时,我发现了原因:我的弹出菜单的项目不在菜单栏上。 wxWidgets 将菜单项的 ID 发送到菜单栏以获取文本,在这种情况下显然失败了。

    花了一些功夫,但我找到了解决问题的方法:

    ////////////////////////////////////////////////////////////////////////////
    // In a header file...
    
    class PopupMenu: public wxMenu {
        public: //
        PopupMenu(): mPushed(false) { }
    
        void OnOpen(wxMenuEvent &evt);
        void OnClose(wxMenuEvent &evt);
        void OnShowMenuHelp(wxMenuEvent &evt);
    
        private: //
        bool mPushed;
    
        DECLARE_EVENT_TABLE()
    };
    
    ////////////////////////////////////////////////////////////////////////////
    // In a cpp file...
    
    BEGIN_EVENT_TABLE(PopupMenu, wxMenu)
        EVT_MENU_OPEN(PopupMenu::OnOpen)
        EVT_MENU_CLOSE(PopupMenu::OnClose)
        EVT_MENU_HIGHLIGHT(wxID_ANY, PopupMenu::OnShowMenuHelp)
    END_EVENT_TABLE()
    
    void PopupMenu::OnOpen(wxMenuEvent &evt) {
        if (!mPushed) {
            // Clear it
            findStatusBar()->PushStatusText(wxString());
            mPushed = true;
        }
    }
    
    void PopupMenu::OnClose(wxMenuEvent &evt) {
        if (mPushed) {
            findStatusBar()->PopStatusText();
            mPushed = false;
        }
    }
    
    void PopupMenu::OnShowMenuHelp(wxMenuEvent &evt) {
        if (mPushed) {
            findStatusBar()->SetStatusText(GetHelpString(evt.GetMenuId()));
        } else {
            findStatusBar()->PushStatusText(GetHelpString(evt.GetMenuId()));
            mPushed = true;
        }
    }
    

    findStatusBar 是一个方便的函数,它定位程序的框架窗口并在其上调用GetStatusBar。)

    现在我只是从PopupMenu 派生一个类,用于我需要的任何弹出窗口。结果很完美。

    可能有一种更简单的方法可以解决这个问题,但是如果没有将弹出窗口的项目放在菜单栏上,我就找不到它。

    【讨论】:

    • 这段代码应该适用于弹出窗口中的任何菜单项吗?我无法管理弹出窗口中每个选项的突出显示事件。
    • 据我所知,应该。不过,这是使用旧版本的 wxWidgets 时的情况,当前版本可能有所改变。
    【解决方案2】:

    Head Geek 的解决方案不适用于 wxWidgets 3.0.2,但我发现了一个不同的解决方案:使用 Bind 在包含单击控件的 wxFrame 上临时注册 wxEVT_MENU_HIGHLIGHT 事件处理程序。完整示例:

    class FunctionMenuWindow : public wxWindow
    {
    public:
        int option;
    
        FunctionMenuWindow(wxWindow *parent) : wxWindow(parent, -1), option(0), mPushed(false)
        {
            this      ->Bind(wxEVT_MENU          , &FunctionMenuWindow::OnMenu     , this, wxID_ANY);
            theMainWin->Bind(wxEVT_MENU_OPEN     , &FunctionMenuWindow::OnOpen     , this, wxID_ANY);
            theMainWin->Bind(wxEVT_MENU_CLOSE    , &FunctionMenuWindow::OnClose    , this, wxID_ANY);
            theMainWin->Bind(wxEVT_MENU_HIGHLIGHT, &FunctionMenuWindow::OnHighlight, this, wxID_ANY);
        }
    
        ~FunctionMenuWindow()
        {
            theMainWin->Unbind(wxEVT_MENU_OPEN     , &FunctionMenuWindow::OnOpen     , this, wxID_ANY);
            theMainWin->Unbind(wxEVT_MENU_CLOSE    , &FunctionMenuWindow::OnClose    , this, wxID_ANY);
            theMainWin->Unbind(wxEVT_MENU_HIGHLIGHT, &FunctionMenuWindow::OnHighlight, this, wxID_ANY);
        }
    
    private:
        void OnMenu(wxCommandEvent& event)
        {
            option = event.GetId();
        }
    
        void OnOpen(wxMenuEvent &evt)
        {
            this->mMenu = evt.GetMenu();
            if (!mPushed)
            {
                theMainWin->GetStatusBar()->PushStatusText(wxString());
                mPushed = true;
            }
        }
    
        void OnClose(wxMenuEvent &evt)
        {
            if (mPushed)
            {
                theMainWin->GetStatusBar()->PopStatusText();
                mPushed = false;
            }
        }
    
        const wxString GetHelpString(wxMenuEvent &evt)
        {
            if (evt.GetMenuId() < 0)
                return wxString();
            else
                return mMenu->GetHelpString(evt.GetMenuId());
        }
    
        void OnHighlight(wxMenuEvent &evt)
        {
            if (mPushed)
                theMainWin->GetStatusBar()->SetStatusText(GetHelpString(evt));
            else
            {
                theMainWin->GetStatusBar()->PushStatusText(GetHelpString(evt));
                mPushed = true;
            }
        }
    
        bool mPushed;
        wxMenu* mMenu;
    };
    
    ///////////////////////////////////////////////////////////////////
    
    void ShowMenu()
    {
        FunctionMenuWindow funcWindow(theMainWin);
        wxMenu *menu = new wxMenu;
    
        // ... set up wxMenu ...
    
        funcWindow.PopupMenu(menu);
    
        switch(funcWindow.option)
        {
            // ... switch by wxID as usual ...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-11-22
      • 2019-05-28
      • 2019-08-10
      • 1970-01-01
      • 1970-01-01
      • 2016-10-04
      • 2020-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多