惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
雷峰网
雷峰网
量子位
V
V2EX
S
SegmentFault 最新的问题
月光博客
月光博客
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
V
Visual Studio Blog
大猫的无限游戏
大猫的无限游戏
T
Tailwind CSS Blog
博客园_首页
博客园 - Franky
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
美团技术团队
Y
Y Combinator Blog
The Cloudflare Blog
C
Check Point Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
腾讯CDC
B
Blog
Stack Overflow Blog
Stack Overflow Blog
P
Proofpoint News Feed

博客园 - 夏天/isummer

vcpkg的安装,配置vs2022, 全局使用,清单使用 Visual Studio 2022中配置Eigen.Natvis文件,实现Debug查看:Eigen库查看矩阵与向量的值 “模型法线到视图法线”的变换矩阵(normal matrix)的计算和作用 python 用control库绘制自动控制原理中的根轨迹: C++ 无法从“const char [ ]”转换为“char *” 根据文件内存字节数,返回文件占用内存大小:单位:T,G,M,K,B 泛洪算法(Flood fill Algorithm):符号洪水填充算法 opengl中的glDrawElements 用法和glDrawArray opengl中的VBO,IBO,VAO,EBO总结: OpenGL着色器Shader小结 VS2022 在编译大型项目出现:c/c++ intellance 操作-优化VS2022,提高Intellance速度 用VS2022创建空桌面程序【Empty】运行wxWidgets应用,报错:MSVCRTD.lib(exe_main.obj) : error LNK2019: 无法解析的外部符号 main VS下使用全局配置的方式使用VCPKG vcpkg 安装过程中install的参数: ApriTags应用 【/MT、/MTd、/MD、/MDd】C++ 出现异常“.... \debug_heap.cpp Line:980 Expression:__acrt_first_block==header"【已解决】 - 夏天/isummer QString的tostdstring问题-提示堆栈内存溢出(2024.12) vsftpd和FileZiler配置:本地登录,支持上传-下载-删除文件和目录-添加文件和目录 PyQt开发-mkvirtualenv虚拟环境 线程池ThreadPool, C++ github 命令git下载失败: Failed to connect to github.com port 443 解决方案,解决CMAKE中下载其他库失败的问题
wsGLCanvas中的OnPaint和OnSize的调用顺序
夏天/isummer · 2026-05-01 · via 博客园 - 夏天/isummer

在 wxGLCanvas 中,OnSize() 与 OnPaint() 的调用顺序遵循 “先尺寸、后绘制” 的核心规则,且在不同场景下有明确时序。
一、窗口初始化(首次显示)
OnSize () 先触发:窗口创建 / 显示时,系统先确定画布尺寸,触发 wxEVT_SIZE → 执行 OnSize()。
OnPaint () 后触发:尺寸确定后,系统触发 wxEVT_PAINT → 执行 OnPaint() 完成首次绘制。
二、窗口调整大小(拖动 / 最大化 / 还原)
OnSize () 触发:尺寸变化 → OnSize() 执行(更新视口、投影矩阵等)。
OnPaint () 自动 / 手动触发:
若创建 wxGLCanvas 时带 wxFULL_REPAINT_ON_RESIZE 样式:OnSize() 执行后,系统自动触发 OnPaint() 重绘。
若无该样式:需在 OnSize() 末尾手动调用 Refresh() / Update() 触发 OnPaint(),否则可能不重绘。
三、窗口被遮挡 / 暴露(仅重绘)
仅触发 OnPaint(),不触发 OnSize()。
四、关键注意事项(避坑)
1. 上下文有效性(最常见崩溃点)
OnSize() 执行时,wxGLContext 可能尚未创建或未激活,直接调用 glViewport() 等 GL 函数会崩溃。

正确写法:

void MyGLCanvas::OnSize(wxSizeEvent& event) {
    event.Skip(); // 必须调用基类处理

    // 1. 检查上下文是否存在
    if (!GetContext()) return;

    // 2. 激活当前上下文(必须)
    SetCurrent(*GetContext());

    // 3. 获取尺寸并更新视口/投影
    wxSize sz = GetClientSize();
    glViewport(0, 0, sz.x, sz.y);
    // ... 更新投影矩阵
}

2. 延迟尺寸处理(跨平台兼容)

  部分平台(如 GTK)会在窗口完全可见前触发 OnSize(),此时 GL 状态无效。

   推荐方案:OnSize() 仅标记尺寸变化,OnPaint() 中统一处理:

// 类成员
bool m_sizeChanged = false;
wxSize m_newSize;

void MyGLCanvas::OnSize(wxSizeEvent& event) {
    event.Skip();
    m_newSize = GetClientSize();
    m_sizeChanged = true;
    Refresh(); // 触发重绘
}

void MyGLCanvas::OnPaint(wxPaintEvent& event) {
    wxPaintDC dc(this);
    SetCurrent(*GetContext());

    // 先处理尺寸变化
    if (m_sizeChanged) {
        glViewport(0, 0, m_newSize.x, m_newSize.y);
        // ... 更新投影
        m_sizeChanged = false;
    }

    // 再执行绘制
    glClear(...);
    // ... 绘制逻辑
    SwapBuffers();
}

3. 样式与重绘控制

   创建 wxGLCanvas 时建议添加 wxFULL_REPAINT_ON_RESIZE,确保调整大小后自动重绘:

MyGLCanvas::MyGLCanvas(...)
    : wxGLCanvas(parent, id, pos, size, 
                 wxFULL_REPAINT_ON_RESIZE | wxBORDER_NONE, 
                 name, attribs) {
    // ...
}
场景调用顺序触发条件
窗口初始化 OnSize()OnPaint() 窗口首次显示
调整大小(带样式) OnSize()OnPaint() 拖动 / 最大化,自动重绘
调整大小(无样式) OnSize() → (需 Refresh()) → OnPaint() 手动触发重绘
窗口暴露 / 刷新 OnPaint() 遮挡后显示、手动 Refresh()

endl;