【问题标题】:Background image flickering of wxWidgets PanelwxWidgets Panel的背景图片闪烁
【发布时间】:2016-03-19 21:31:59
【问题描述】:

我想要完成的是有两个Panels,一个用于绘制,另一个用于保存工具,所以我使用默认的Panel 和整个屏幕的大小在@ 上绘制形状987654323@ 和自定义的Panel 用于工具,所以我可以为其添加背景toolsPanel

#ifndef WXIMAGEPANEL_H
#define WXIMAGEPANEL_H

#include <wx/wx.h>
#include <wx/custombgwin.h>
#include <wx/dcbuffer.h>

class wxImagePanel : public wxCustomBackgroundWindow<wxPanel>
{
public:
    wxImagePanel();
    wxImagePanel (wxWindow *parent,
                  wxWindowID winid = wxID_ANY,
                  const wxPoint& pos = wxDefaultPosition,
                  const wxSize& sizee = wxDefaultSize,
                  long style = wxTAB_TRAVERSAL | wxNO_BORDER,
                  const wxString& name = wxPanelNameStr);
    void SetBackgroundImage(const wxBitmap & background);
    virtual ~wxImagePanel();
protected:
private:
    const wxBitmap * ptr_backgorund;

    void paintEvent(wxPaintEvent & evt);
    void OnEraseBackground(wxEraseEvent& event);
    DECLARE_EVENT_TABLE()
};

#endif // WXIMAGEPANEL_H
----------------------------------------------------
#include "wxImagePanel.h"

wxImagePanel::wxImagePanel()
{
    //ctor
    //SetBackgroundStyle(wxBG_STYLE_PAINT);
}

wxImagePanel::wxImagePanel (wxWindow *parent,
                            wxWindowID winid ,
                            const wxPoint& pos ,
                            const wxSize& sizee ,
                            long style ,
                            const wxString& name)
{
    Create(parent,winid,pos,sizee,style,name);
    //SetBackgroundStyle(wxBG_STYLE_PAINT);
}
void wxImagePanel::SetBackgroundImage(const wxBitmap & background)
{
    this->ptr_backgorund = &background;
    SetBackgroundBitmap(background);
}

wxImagePanel::~wxImagePanel()
{
    //dtor
    if(ptr_backgorund)
        delete ptr_backgorund;
}

BEGIN_EVENT_TABLE(wxImagePanel, wxPanel)
    //EVT_PAINT(wxImagePanel::paintEvent)
    EVT_ERASE_BACKGROUND(wxImagePanel::OnEraseBackground)
END_EVENT_TABLE()

void wxImagePanel::OnEraseBackground(wxEraseEvent& event)
{

}

void wxImagePanel::paintEvent(wxPaintEvent & evt)
{
    wxAutoBufferedPaintDC dc(this);
    PrepareDC(dc);
    if(ptr_backgorund)
        dc.DrawBitmap( *ptr_backgorund, 0, 0);
}

我已经尝试了两种方式(自己绘制背景,并使用SetBackgroundBitmap 方法),当我在MouseMove event 上调用drawPanel-&gt;Refresh() 时,两种方式都在闪烁,所以这里缺少什么,导致@ 987654331@闪烁?

【问题讨论】:

    标签: c++ c++11 flicker wxwidgets


    【解决方案1】:

    如果您在每次鼠标移动时在整个窗口上调用Refresh(),闪烁是不可避免的,这根本不应该这样做。至少,您只需要刷新真正需要重新绘制的小区域而不是整个窗口,这会显着减少闪烁,但可能仍然不够。最好的解决方案是使用(不幸的是仍然没有记录)wxOverlay 类在鼠标移动到窗口顶部时覆盖您正在绘制的任何内容。

    【讨论】:

    • 但不是重绘整个窗口,我只是重绘drawPanel,我不明白为什么它会影响另一个面板?
    • 您显示的代码中没有drawPanel,所以很难说出了什么问题。但是,如果您不想闪烁,则避免过多刷新的基本观点仍然有效。
    • 那么拥有panel 的最佳方式是什么,我将继续使用它,比如Window Paint 应用程序,我想实现类似的东西,我有工具和区域面板。
    【解决方案2】:

    尝试像这样刷新:

    window->Refresh(false)
    

    这是一个类似的帖子,其中包含一条非常有用的建议:在刷新时,“选项 eraseBackground = FALSE 对于避免闪烁非常重要”

    how to animate picture without making it flicker using wxWidgets in erlang?

    文档说 Refresh 以递归方式重绘“窗口及其所有子窗口(wxGTK1 下未实现的除外)”。尽管我不理解这种行为,但我怀疑 Refresh 的递归性质会导致闪烁,因为我通常在 Windows 7 下遇到它,但在 Linux GTK 下却没有(使用完全相同的代码)。 但是,在 Windows 10 下,即使使用 eraseBackground = TRUE,我也看不到任何闪烁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      • 2014-03-19
      • 1970-01-01
      • 2013-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多