背景图像闪烁的wxWidgets面板

时间:2015-12-14 11:54:35

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

我想要完成的是有两个Panels,一个用于绘制,另一个用于保存工具,所以我使用默认的Panel和整个屏幕的大小在drawPanel上绘制形状,并在工具顶部使用自定义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方法),在drawPanel->Refresh() MouseMove上调用event时两种方式都会闪烁,所以我在这里失踪了,导致toolsPanel闪烁?

2 个答案:

答案 0 :(得分:0)

如果您在每次鼠标移动时在整个窗口上调用Refresh(),则闪烁是不可避免的,这根本就不应该完成。至少,您需要刷新真正需要重新绘制的小区域而不是整个窗口,这会显着减少闪烁,但可能仍然不够。最好的解决方案是使用(遗憾的是未记录的)wxOverlay类来叠加当鼠标在窗口顶部移动时所绘制的内容。

答案 1 :(得分:0)

尝试像这样刷新:

window->Refresh(false)

这是一个类似的线程,包含一条非常有用的建议:在Refresh上,“选项eraseBackground = FALSE对于避免闪烁是非常重要的”

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

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