wxWidgets:处理wxEVT_PAINT

本文详细介绍了如何通过继承wxFrame创建自定义窗口,并在窗口上实现绘图操作。重点阐述了在绘图前设置背景模式、窗口背景色以及绘制文字的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们仍然以继承于wxFrame的MyFrame作为例子。

MyFrame.h:

class MyFrame : public wxFrame
{
    ......
private:
    ......
    void OnPaint(wxPaintEvent &event);
};

MyFrame.cpp

MyFrame :: MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
              : wxFrame(NULL, wxID_ANY, title, pos, size)
{
    // 设置窗口默认背景色
    SetBackgroundColour(*wxWHITE);
    // Bind paint event
    Bind(wxEVT_PAINT, &MyFrame::OnPaint, this);
}

// paint event handler
void MyFrame :: OnPaint(wxPaintEvent &event)
{
    wxPaintDC dc(this);
    dc.SetTextBackground(*wxRED);
    dc.SetTextForeground(*wxYELLOW);
    dc.SetBackgroundMode(wxSOLID);
    dc.DrawText(L"Exercise 1", 0, 0);
}

上面的代码中,绘图前将文字背景模式设置为wxSOLID,否则无法正确显示出文字背景色。

另外,在MyFrame的构造函数中将窗口背景设置为白色。在Paint前,Windows将会用该颜色填充无效区域。

# 📘 第二章:wxWidgets 核心可视化组件 ## 2.2 wxPanel - 容器控件 --- ### 🔍 章节概述 **`wxPanel`** 是一个轻量级的窗口容器控件,常用于组织和管理其他控件。它继承自 `wxWindow`,支持布局管理、绘图、背景色设置等高级功能,是构建 GUI 界面结构的重要组成部分。 该控件适用于以下常见场景: - 组织多个控件形成逻辑区域(如“用户信息”、“高级设置”) - 实现局部布局管理 - 自定义绘制界面元素(如图表、动画) - 嵌套使用实现复杂的 UI 分区设计 本节将讲解: - `wxPanel` 的基本用途与创建方法 - 如何嵌套其他控件并进行布局 - 设置背景颜色与样式 - C++ 和 Python 示例代码 - 与 `wxSizer` 的配合使用技巧 - 自定义绘制面板内容的方法 --- ### **属性** | 属性名 | 类型 | 说明 | |--------|------|------| | `Parent` | `wxWindow*` | 父容器指针 | | `BackgroundColour` | `wxColour` | 背景色 | ### **方法** | 方法名 | 返回值 | 说明 | |--------|--------|------| | `SetBackgroundColour(const wxColour& colour)` | `void` | 设置背景色 | | `GetClientSize()` | `wxSize` | 获取客户区尺寸 | ### **事件** | 事件类型 | 说明 | |----------|------| | `无` | 仅用于布局容器,无交互事件 | --- ## ✅ C++ 实现代码(wxWidgets) ```cpp #include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); }; class MyFrame : public wxFrame { public: MyFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(400, 300)) { // 创建主 Panel(作为整个窗口的内容承载) wxPanel* mainPanel = new wxPanel(this); // 创建水平 Box Sizer wxBoxSizer* hSizer = new wxBoxSizer(wxHORIZONTAL); // 创建两个子 Panel 并添加到主布局中 wxPanel* leftPanel = new wxPanel(mainPanel); leftPanel->SetBackgroundColour(*wxLIGHT_GREY); wxPanel* rightPanel = new wxPanel(mainPanel); rightPanel->SetBackgroundColour(wxColour(255, 220, 220)); // 淡红色 // 添加按钮到左右 Panel 中 wxButton* btn1 = new wxButton(leftPanel, wxID_ANY, "左边按钮"); wxButton* btn2 = new wxButton(rightPanel, wxID_ANY, "右边按钮"); // 设置每个 Panel 的布局 wxBoxSizer* leftSizer = new wxBoxSizer(wxVERTICAL); leftSizer->Add(btn1, 0, wxALIGN_CENTER | wxALL, 10); leftPanel->SetSizer(leftSizer); wxBoxSizer* rightSizer = new wxBoxSizer(wxVERTICAL); rightSizer->Add(btn2, 0, wxALIGN_CENTER | wxALL, 10); rightPanel->SetSizer(rightSizer); // 将两个 Panel 添加到主布局中 hSizer->Add(leftPanel, 1, wxEXPAND | wxALL, 5); hSizer->Add(rightPanel, 1, wxEXPAND | wxALL, 5); mainPanel->SetSizer(hSizer); } }; bool MyApp::OnInit() { MyFrame* frame = new MyFrame("wxPanel 示例 - C++"); frame->Show(true); return true; } wxIMPLEMENT_APP(MyApp); ``` --- ## ✅ Python 实现代码(wxPython) ```python import wx class MyFrame(wx.Frame): def __init__(self, *args, **kw): super(MyFrame, self).__init__(*kw) # 主 Panel main_panel = wx.Panel(self) # 水平布局 h_sizer = wx.BoxSizer(wx.HORIZONTAL) # 左边 Panel left_panel = wx.Panel(main_panel) left_panel.SetBackgroundColour(wx.Colour(211, 211, 211)) # 浅灰色 btn1 = wx.Button(left_panel, label="左边按钮") left_sizer = wx.BoxSizer(wx.VERTICAL) left_sizer.Add(btn1, 0, wx.ALIGN_CENTER | wx.ALL, 10) left_panel.SetSizer(left_sizer) # 右边 Panel right_panel = wx.Panel(main_panel) right_panel.SetBackgroundColour(wx.Colour(255, 220, 220)) # 淡红色 btn2 = wx.Button(right_panel, label="右边按钮") right_sizer = wx.BoxSizer(wx.VERTICAL) right_sizer.Add(btn2, 0, wx.ALIGN_CENTER | wx.ALL, 10) right_panel.SetSizer(right_sizer) # 添加到主布局 h_sizer.Add(left_panel, 1, wx.EXPAND | wx.ALL, 5) h_sizer.Add(right_panel, 1, wx.EXPAND | wx.ALL, 5) main_panel.SetSizer(h_sizer) self.SetTitle("wxPanel 示例 - Python") self.SetSize((400, 300)) self.Centre() class MyApp(wx.App): def OnInit(self): frame = MyFrame(None) frame.Show(True) return True if __name__ == '__main__': app = MyApp(False) app.MainLoop() ``` --- ## 🧩 控件常用样式说明(C++ / wxWidgets) | 样式名称 | 含义说明 | |----------------------|--------------------------------------------------------| | `wxTAB_TRAVERSAL` | 允许 Tab 键切换焦点 | | `wxFULL_REPAINT_ON_RESIZE` | 窗口大小变化时重绘全部内容 | > ⚠️ 注意:Python 中传入方式为 `style=wx.TAB_TRAVERSAL` 等。 --- ## 📌 主要功能与方法 | 方法名 | 描述 | |---------------------------|--------------------------------------------------------------| | `SetBackgroundColour(col)` | 设置背景颜色 | | `SetForegroundColour(col)` | 设置前景颜色(文本颜色) | | `SetFont(font)` | 设置字体 | | `GetParent()` | 获取父控件 | | `SetSizer(sizer)` | 设置布局管理器 | | `Refresh()` | 刷新面板内容(触发重绘) | | `Update()` | 强制立即更新界面 | --- ## 🎨 自定义绘制示例(C++) ```cpp class CustomPanel : public wxPanel { public: CustomPanel(wxWindow* parent) : wxPanel(parent) { Bind(wxEVT_PAINT, &CustomPanel::OnPaint, this); } private: void OnPaint(wxPaintEvent& event) { wxPaintDC dc(this); dc.SetBrush(*wxGREEN_BRUSH); dc.DrawCircle(GetSize().GetWidth() / 2, GetSize().GetHeight() / 2, 50); } }; ``` --- ## 📌 总结 | 特性 | 描述 | |---------------------|--------------------------------------------------------------| | 控件名称 | `wxPanel` | | 功能 | 提供控件容器功能,支持布局管理和视觉分区 | | 支持平台 | Windows / Linux / macOS | | 推荐用途 | 分组控件、布局管理、自定义界面绘制 | | 开发建议 | 配合 `wxSizer` 使用;合理使用背景色区分功能区域;避免过度嵌套 | --- 📌 **扩展功能建议:** - 使用 `wxScrolled<wxPanel>` 实现滚动面板 - 在 `wxPanel` 上绘制图形或实现动画效果 - 作为对话框、工具栏、状态栏的容器使用 - 结合 `wxNotebook` 或 `wxSplitterWindow` 构建复杂布局 - 替代 `wxWindow` 用于需要布局支持的场合 请根据上面的内容,实现扩展功能,要求,C++和PYTHON双语言支持,并对每一行代码都进行中文注解
最新发布
07-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值