返回介绍

10.4 使用 wxCursor 编程

发布于 2025-03-08 15:26:47 字数 6501 浏览 0 评论 0 收藏 0

光标用来指示鼠标指针当前的位置.你可以给某个窗口指定不同的光标以便提示用户这个窗口期待某种类型的鼠标操作.和图标一样,光标也是一种始终带有透明遮罩的小图片,可以使用一般的构造函数或者是平台相关的构造函数来创建.其中的一些构造函数还需要相对于整个图片的左上角指定一个热点位置,当鼠标点击的时候,热点所在的位置将作为鼠标点击的位置。

下表列举了光标相关的函数

wxCursor光标可以从 wxImage 对象,二进制数据,系统定义的光标标识符以及光标文件来创建。
Ok如果光标数据已经具备,则返回 True。

创建一个光标

创建光标最简单的方法是通过系统提供的光标标识符,如下面的例子所示:

wxCursor cursor(wxCURSOR_WAIT);

下表列出了目前支持的光标标识符和它们的光标的样子(依照平台的不同会有些变化)

wxCURSOR_ARROW标准光标。
wxCURSOR_RIGHT_ARROW标准反向光标。
wxCURSOR_BLANK透明光标。
wxCURSOR_BULLSEYE近视眼。
wxCURSOR_CROSS十字。
wxCURSOR_HAND手。
wxCURSOR_IBEAMI 字光标。
wxCURSOR_LEFT_BUTTON按左键(GTK+ only)。
wxCURSOR_MAGNIFIER放大镜。
wxCURSOR_MIDDLE_BUTTON按中键(译者注:原书图片有误) (GTK+ only)。
wxCURSOR_NO_ENTRY禁止通行。
wxCURSOR_PAINT_BRUSH画刷。
wxCURSOR_PENCIL铅笔。
wxCURSOR_POINT_LEFT向左。
wxCURSOR_POINT_RIGHT向右。
wxCURSOR_QUESTION_ARROW带问号的箭头。
wxCURSOR_RIGHT_BUTTON按右键(译者注:图片有误) (GTK+ only)。
wxCURSOR_SIZENESW东北到西南伸缩。
wxCURSOR_SIZENS南北伸缩。
wxCURSOR_SIZENWSE西北到东南伸缩。
wxCURSOR_SIZEWE东西伸缩。
wxCURSOR_SIZING一般伸缩。
wxCURSOR_SPRAYCAN画刷。
wxCURSOR_WAIT等待。
wxCURSOR_WATCH查看。
wxCURSOR_ARROWWAIT后台忙。

你还可以使用预定义光标指针 wxSTANDARD_CURSOR, wxHOURGLASS_CURSOR 和 wxCROSS_CURSOR。

另外在 windows 和 Mac 平台上还可以从对应的资源文件中加载光标:

//windows 平台
wxCursor cursor(wxT("cursor_resource"), wxBITMAP_TYPE_CUR_RESOURCE,
                 hotSpotX, hotSpotY);
// Mac 平台
wxCursor cursor(wxT("cursor_resource"), wxBITMAP_TYPE_MACCUR_RESOURCE);

你还可以通过 wxImage 对象创建光标,而"热点"则要通过 wxImage::SetOptionInt 函数设置.之所以要设置热点,是因为很多光标不太适合使用默认的左上角作为热点,比如对于十字光标来说,你可能希望将其十字交叉的地方作为热点.下面的代码演示了怎样从一个 PNG 文件中产生设置了热点的光标:

// 用 wxImage 创建光标
wxImage image(wxT("cursor.png"), wxBITMAP_TYPE_PNG);
image.SetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X, 5);
image.SetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y, 5);
wxCursor cursor(image);

使用 wxCursor

每个窗口都可以设置一个对应的光标,这个光标在鼠标进入这个窗口的时候显示,如果一个窗口没有设置光标,其父窗口的光标将被显示,如果所有的父窗口都没有设置光标,则系统默认光标被显示:

使用下面的代码给窗口设置一个光标:

window->SetCursor(wxCursor(wxCURSOR_WAIT));

使用 wxSetCursorEvent

在 windows 系统或者是 Mac OS X 系统上,有一些小地方我们需要注意一下.举个例子,如果你自己实现了一个容器类,比方说是一个分割窗口,并且给它设置了一个特殊的光标(比如说 wxCURSOR_WE 用来表明某个分割条是可以被拉动的),然后你在这个分割窗口中放置了两个子窗口,如果你没有给这两个子窗口设置光标的话,当光标在子窗口上移动时,它们可能会不恰当的显示其父窗口,那个 wxCURSOR_WE 光标.而本来你是希望只有在鼠标移动到分割条上的时候才显示的。

要告诉 wxWidgets 某个光标只应该在某种情况下被显示,你可以增加一个 wxSetCursorEvent 事件的处理函数,这个事件在 Windows 和 Mac 平台上,当需要设置光标的时候(通常是鼠标在窗口间移动的时候) 被产生.在这个事件处理函数中可以调用 wxSetCursorEvent::SetCursor 来设置一个特殊的光标.如下所示:

BEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow)
    EVT_SET_CURSOR(wxSplitterWindow::OnSetCursor)
END_EVENT_TABLE()
// 指示光标只应该被设置给分割条
void wxSplitterWindow::OnSetCursor(wxSetCursorEvent& event)
{
    if ( SashHitTest(event.GetX(), event.GetY(), 0) )
    {
        // 使用默认的处理
        event.Skip();
    }
    //else:什么也不作,换句话说,不调用 Skip.则事件表不会被继续搜索
}

在这个例子中,当鼠标指针移过分割条的时候,SashHitTest 函数返回 True,因此 Skip 函数被调用,事件表调用失败,这和没有定义这个事件表的效果是一样的,导致 wxWidgets 象往常一样显示指定给窗口的光标(wxCURSOR_WE).而如果 SashHitTest 函数返回 False,则表明光标是在子窗口上移动,这时候应该不显示我们指定的光标,因此我们不调用 Skip 函数,让事件表匹配成功,则事件表将不会在继续匹配,这将使得 wxWidgets 认为这个窗口没有被指定光标,因此.在这种情况下,即使子窗口自己没有光标(象 wxTextCtrl 这种控件,一般系统会指定一个它自己的光标,不过 wxWidgets 对这个是不感知的),也将不会使用我们指定给父窗口的光标。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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