首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >滚动时wxScrolledWindow中的图像损坏

滚动时wxScrolledWindow中的图像损坏
EN

Stack Overflow用户
提问于 2018-02-17 21:29:54
回答 1查看 312关注 0票数 0

我想使用wxSplitterWindow之一使用wxScrolledWindow查看图像。我从wxPanel派生类,并将其添加到wxScrolledWindow中。但结果不是我想要的。

代码语言:javascript
运行
复制
class ImagePanel : public wxPanel
{
public:
    //ImagePanel(wxFrame* parent);
    ImagePanel(wxWindow* parent);
    void paintEvent(wxPaintEvent& event);
    void paintNow();

    void setBitmap(wxBitmap& imBitmap);
    void setBitmap(wxImage& img);

    int GetHeight();
    int GetWidth();

    void render(wxDC& dc);

    DECLARE_EVENT_TABLE()
private:
    wxBitmap curBitmap;
};

油漆事件:

代码语言:javascript
运行
复制
void ImagePanel::paintEvent(wxPaintEvent& event)
{
    wxBufferedPaintDC dc(this);
    render(dc);
}

我是这样将接口编写成主框架构造函数的:

代码语言:javascript
运行
复制
topSizer = new wxBoxSizer(wxVERTICAL);

    topSplitter = new wxSplitterWindow(this,ID_TOPSPLITTER,wxDefaultPosition,wxDefaultSize,wxSP_LIVE_UPDATE|wxSP_3D);
    topSizer->Add(topSplitter,1,wxALL|wxEXPAND,0);

    imagePanel = new wxPanel(topSplitter,ID_IMAGEPANEL);
    imageSizer = new wxBoxSizer(wxVERTICAL);
    imagePanel->SetSizer(imageSizer);
    optionPanel = new wxPanel(topSplitter,ID_OPTIONPANEL);
    optionSizer = new wxBoxSizer(wxVERTICAL);
    optionPanel->SetSizer(optionSizer);
    topSplitter->SplitVertically(imagePanel, optionPanel);
    topSplitter->SetMinimumPaneSize(200);

    //===========================================
    //image panel interface
    imageScWindow=new wxScrolledWindow(imagePanel,ID_IMAGESCWINDOW,wxDefaultPosition,wxDefaultSize,
                                       wxVSCROLL|wxHSCROLL|wxALL|wxALWAYS_SHOW_SB|wxFULL_REPAINT_ON_RESIZE);
    imgArea = new ImagePanel(imageScWindow);
    imageSizer->Add(imageScWindow,1,wxEXPAND,0);

    scrollSizer = new wxBoxSizer(wxVERTICAL);
    imageScWindow->SetSizer(scrollSizer);
    scrollSizer->Add(imgArea,1,wxEXPAND,0);
    imageScWindow->SetTargetWindow(imgArea);

这是加载图像的函数:

代码语言:javascript
运行
复制
void MainFrame::Setpic(wxCommandEvent& event)

{
    wxString path = GetCurrentWorkingDir()+wxT("\\")+tmptxt1->GetValue();
    wxImage img(path);
    wxBitmap imBitmap(img,-1);
    imgArea->setBitmap(imBitmap);
    imageScWindow->SetScrollbars(1,1,imgArea->GetWidth(),imgArea->GetHeight());
    imageScWindow->Refresh();
}

这就是我得到的:https://i.imgur.com/x1GIlrl.png

我还尝试在构造函数中这样做,而不使用SetTargetArea:

代码语言:javascript
运行
复制
//===========================================
    //image panel interface
    imageScWindow=new wxScrolledWindow(imagePanel,ID_IMAGESCWINDOW,wxDefaultPosition,wxDefaultSize,
                                       wxVSCROLL|wxHSCROLL|wxALL|wxALWAYS_SHOW_SB|wxFULL_REPAINT_ON_RESIZE);
    imgArea = new ImagePanel(imageScWindow);
    imageSizer->Add(imageScWindow,1,wxEXPAND,0);

    scrollSizer = new wxBoxSizer(wxVERTICAL);
    imageScWindow->SetSizer(scrollSizer);
    scrollSizer->Add(imgArea,1,wxEXPAND,0);

然后图像显示正确,但如果我改变帧大小或移动拆分器,滚动条消失,我必须再次设置他们在某些地方。然后我试着这样做:

代码语言:javascript
运行
复制
int prvx,prvy;
void ImagePanel::paintEvent(wxPaintEvent& event)
{
    reinterpret_cast<wxScrolledWindow*>(this->GetParent())->GetViewStart(&prvx,&prvy);
    reinterpret_cast<wxScrolledWindow*>(this->GetParent())->SetScrollbars(1,1,curBitmap.GetWidth(),curBitmap.GetHeight());
    reinterpret_cast<wxScrolledWindow*>(this->GetParent())->Scroll(wxPoint(prvx,prvy));
    wxBufferedPaintDC dc(this);
    render(dc);
}

它显示正常,但滚动时滞后,即使没有wxFULL_REPAINT_ON_RESIZE在wxScrolledWindow中。其原因是:如果我将它添加到OnSize事件中,程序就会崩溃。该怎么办呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-17 23:41:49

我不知道从哪里开始回答你的问题。这是一个最小的框架样本,它有一个分割器,左边有位图,右边有一个面板。我希望你能修改这个样本来做你想做的事。

代码语言:javascript
运行
复制
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif

#include <wx/scrolwin.h>
#include <wx/splitter.h>
#include <wx/dcbuffer.h>

class MyFrame : public wxFrame
{
    public:
        MyFrame( wxWindow* parent, int id = wxID_ANY, wxString title = "Demo",
                 wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize,
                 int style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
    private:
        void OnScrollPaint( wxPaintEvent& event );

        wxScrolledCanvas* m_canvas;
        wxBitmap m_bitmap;
};

MyFrame::MyFrame( wxWindow* parent, int id, wxString title, wxPoint pos,
                  wxSize size, int style )
        :wxFrame( parent, id, title, pos, size, style )
{
    m_bitmap=wxBitmap ("test.png", wxBITMAP_TYPE_PNG   );

    wxSplitterWindow* m_splitter1
        = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition,
                                wxDefaultSize, wxSP_LIVE_UPDATE );

    m_canvas = new wxScrolledCanvas( m_splitter1, wxID_ANY, wxDefaultPosition,
         wxDefaultSize, wxSTATIC_BORDER|wxHSCROLL|wxVSCROLL );

    m_canvas->SetScrollRate( 5, 5 );
    m_canvas->SetVirtualSize(m_bitmap.GetWidth(), m_bitmap.GetHeight());
    m_canvas->SetBackgroundStyle(wxBG_STYLE_PAINT);
    m_canvas->Bind( wxEVT_PAINT, &MyFrame::OnScrollPaint , this );

    wxPanel* m_panel2 = new wxPanel( m_splitter1, wxID_ANY, wxDefaultPosition,
        wxDefaultSize, wxSTATIC_BORDER|wxTAB_TRAVERSAL );

    m_splitter1->SplitVertically( m_canvas, m_panel2, GetSize().x/2 );
}

void MyFrame::OnScrollPaint( wxPaintEvent& event )
{
    wxAutoBufferedPaintDC dc(m_canvas);
    m_canvas->DoPrepareDC(dc);
    dc.Clear();
    dc.DrawBitmap(m_bitmap,0,0);
}

class MyApp : public wxApp
{
    public:
        virtual bool OnInit()
        {
            wxInitAllImageHandlers();
            MyFrame* frame = new MyFrame(NULL);
            frame->Show();
            return true;
        }
};

wxIMPLEMENT_APP(MyApp);

要运行此操作,请确保将第35行中的"test.png“更改为计算机上实际图像文件的名称(如果图像文件不是png,则更改wxBITMAP_TYPE_PNG )。

重要的部分是:

  1. 将画布的背景样式设置为wxBG_STYLE_PAINT,如第46行所示。
  2. 在油漆处理程序中,调用油漆the上的DoPrepareDC方法。

顺便说一下,我的样本中显示的油漆处理程序不是很好。它每次都会绘制整个位图。一种更好的方法是获取更新区域,只重新绘制所需的部分,但我想保持这个简单。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48846116

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档