加载中...
简简单单,状态栏
第1节:在Windows桌面打个叉
第2节:在窗口上跟踪输出鼠标坐标—Win32版
第3节:你好!wxWidgets
第4节:深入分析基于框架窗口的应用
第5节:玩转主菜单
第6节:简简单单,状态栏
课文封面
  1. 如何创建状态栏?
  2. “面板”是什么?“默认面板”又是什么?
  3. 如何设置面板的固定宽度和动态宽度?
  4. 认识 wxStatusBar 类
  5. 在状态栏实时显示鼠标坐标

0. 课堂视频

状态栏通常被设计成不需要接收用户输入的“静态组件”,是一种常用的,且比较简单的图形界面组件。

1. 创建状态栏

通常在框架主窗口(用户自己写,或IDE向导生成的wxFrame的派生类)的构造函数中,创建状态栏,并指定包含几个子面板(fields)。

框架窗口(也就是程序的主窗口对象)将记住、持有该函数内创建的状态栏。为方便操作,框架窗口基类(wxFrameBase) 提供了本课所学的,与状态栏相关的几个方法,但实际上,这些方法最终涉及状态栏的操作,都由前述的状态栏完成。

方法原型:

virtual wxStatusBar* wxFrame::CreateStatusBar ( int number = 1, long style = wxSTB_DEFAULT_STYLE, wxWindowID id = 0, const wxString & name = wxStatusBarNameStr );

使用示例:
实际调用时,可以忽略多数入参,包括返回值(因为如前所述,当前框架窗口负责持有)。

// 以下代码示例创建一个状态栏,并设置包含3个子面板 CreateStatusBar(3);

2. 设置状态栏子面板文本内容

方法原型:

virtual void SetStatusText (const wxString &text, int number=0);
  • text 指定文本内容
  • number 指定第几个子面板,次序从 0 开始

使用示例:
以下方法设置第0个面板显示 “d2school.com”:

SetStatusText(wxT("d2school.com"), 0);

3. 设置一组面板的宽度

方法原型:

virtual void SetStatusWidths (int n, const int *widths_field);
  • n 指定 widths_fields 指针指向的(整数)元素个数;
  • widths 包含从第一个开始的各面板新宽度;

使用示例:

int widths[] {120, 140, 80}; SetStatusWidths(WXSIZEOF(widths), widths);

由于“数组退化”,此类以“数组”为入参的函数多数都需要带上另一个参数,用于指明数组(将退化为指针)的实际元素个数。此时可以使用 C++2017 新标引入 std::size(),也可以使用 wxWidgets 提供的工具宏 WXSIZEOF()。

上例所设置的三个宽度,都是固定宽度,所设置的三个面板在程序时,宽度固定的。wxWidgets 也支持为状态栏面板设置“动态宽度”,或称为 “比例宽度”,方法就是将指定面板宽度设置为负数。

实际执行效果:当状态栏跟随所在的窗口自动拉伸(宽度变大变小)时,会首先为设为固定宽度的面板,分配固定宽度,余下宽度,交给设置了动态(也就是负数)宽度的面板以负数的绝对值按比例分配。比如有两个面板设置成动态宽度,一为-1,二是-2,则后者实际分配的宽度是前者的两倍。

假设状态栏当前总宽度为 100,已知它有三个子面板,一个使用固定宽度为40,二个使用动态宽度为-1,三个为-2,则此时三者宽度分别为:

  • 面板一:40(固定值)
  • 面板二:20(余下宽度的三分之一,(100-40)*1÷3)
  • 面板三:40(余下宽度的三分之二,(100-40)*2÷3)

4. 设置框架窗口默认状态面板

定义:采用框架窗口作程序主窗口时,框架窗口需要占用状态栏上的一个面板,用来显示诸如菜单项、工具按钮的提示。这个面板就叫默认状态面板。

wxWidgets 默认使用第一个子面板作为默认状态面板,可以通过框架窗口的以下方法来加以修改:

SetStatusBarPane(int n); // n 为面板次序号,从0开始

以下是在主框架窗口的构造过程中,多个状态栏相关方法的综合应用的示例:

CreateStatusBar(3); // 创建状态栏,含三个子面板 // 分别设置三个子面板的显示内容 SetStatusText(wxT("第2学堂 | d2school"), 0); SetStatusText(wxbuildinfo(short_f), 1); SetStatusText(_("Hello Code::Blocks user!"), 2); // 一次性设置三个子面板的宽度,最后一个为动态宽度 int widths[] = {140, 140, -1}; int n = std::size(widths); // 使用 C++ 17 新标提供的方法 SetStatusWidths(n , widths); SetStatusBarPane(2); // 设置第3个面板,也就是最后一个面板为默认面板

5 状态栏实际应用

在状态栏上显示内容,无需涉及窗口的 OnPaint() 事件,而是直接在鼠标移动事件的响应函数中,先依据当前鼠标坐标值,组装出文本内容(wxString),然后直接设定:

void HelloStatusBarFrame::OnMontion(wxMouseEvent& event) { xPos = event.GetPosition().x; yPos = event.GetPosition().y; //// 以下是新增内容 //// wxString info; info << xPos << wxT(" | ") << yPos; SetStatusText(info, 0); //// 新增内容结束 //// this->Refresh(); }

运行效果:

在状态栏上显示鼠标坐标

6 更多知识

搜索 wxStatusBar 即可进入 wxWidges 官方文档中的状态栏类参考文档页面。

https://docs.wxwidgets.org/stable/classwx_status_bar.html