【问题标题】:wxPanel flickering/failure when window is inactive窗口不活动时wxPanel闪烁/失败
【发布时间】:2013-12-12 03:24:11
【问题描述】:

基本上,我有一个实现 OpenGL 的 wxWidget 应用程序 - 后者显示在面板上,可以通过用户输入(单击、拖动等)、wxTimer 或外部进程生成的事件进行更新。当焦点转移到另一个窗口(无论是内部对话框,或完全是另一个应用程序)时,就会出现问题 - wxPanel 在几秒钟后立即停止更新,特别是如果另一个窗口在它上面(有时,被遮挡的一小部分面板仍将继续更新)。重新激活应用程序或调整窗口大小会“解冻”面板,并继续正常操作。

这是我在 wxWidgets 中一直遇到的一个问题,无论是在这种情况下使用 OpenGL 面板还是其他方式。一般来说,我已经能够通过在窗口重新聚焦、窗口大小调整或类似的笨拙的东西时在 Freeze() 和 Thaw() 之间进行多次 SwapBuffer() 调用来解决它,但这些都有可能产生闪烁或其他不可忽略的视觉伪影,并且如果每帧都完成(例如动画需要在非活动窗口中继续播放时),还会影响性能。

不确定的试错期可能会为此产生一些好的和笨拙的东西,但我真的很想知道,处理这个问题的“正确”方法是什么?非常感谢。

下面是代码的骨架供参考:

void MyGLCanvas::Draw(bool focus, int parentID) //This is what's called by the rest of the application
{
    if (focus) { SetFocus(); }  
    SetCurrent();
    wxClientDC dc(this);
    Paint(dc);
}
void MyGLCanvas::Paint(wxDC &dc)
{
    //All OpenGL drawing code here
    glFlush();
    SwapBuffers();
}
void MyGLCanvas::OnPaint(wxPaintEvent& event)
{
    wxPaintDC dc(this);
    Paint(dc);
    event.Skip();
}

【问题讨论】:

    标签: wxwidgets


    【解决方案1】:

    你在这里做了几件奇怪或完全错误的事情:

    1. 不要不要跳过OnPaint() 中的事件。这是 Windows 下 wxWidgets 2.8 中的一个致命错误,即使我们在您的代码在 3.0 中执行此操作后进行了清理,这仍然是一个坏主意。
    2. 不要使用wxClientDC,只需调用Refresh() 并通过调用现有的OnPaint() 处理程序让Windows 重新绘制窗口。
    3. 不要从Draw() 打电话给SetFocus(),这真的没有必要。
    4. 请在绘图前致电SetCurrent()。总是,不仅仅是Draw()

    我不知道其中哪些会导致您遇到问题,但您确实应该改变所有这些问题。有关如何正确执行此操作的示例,请参阅 samples\opengl\cube\cube.cpp

    【讨论】:

      猜你喜欢
      • 2014-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-29
      • 1970-01-01
      • 2015-08-29
      • 2016-01-19
      相关资源
      最近更新 更多