我正在尝试创建一个wxPanel以在其上绘制线条和点。
我的程序包含以下窗口:
MyFrame:从wxFrame继承的默认框架类
Final_Layout:具有父MyFrame(即此指针)的wxPanel的实例,它包含我所有的控件
现在,我正在尝试创建一个新面板Draw_Panel,可以在其上绘制。我想使用wxBoxSizer在Final_Layout之外附加此面板。
所以,我的第一步是初始化面板,我有以下代码:
void MyFrame::Initialize_Draw_Input() {
Draw_Panel = new wxPanel(this, -1); // QUESTION : Who is the parent here? Should it be Final_Layout or "this" pointer?
Draw_Panel ->Connect(wxEVT_PAINT, wxPaintEventHandler(MyFrame::OnPaint));
}
void MyFrame::OnPaint(wxPaintEvent& event)
{
wxPaintDC dc(Draw_Panel );
wxCoord x1 = 50, y1 = 60;
wxCoord x2 = 100, y2 = 60;
dc.DrawLine(x1, y1, x2, y2);
}
但是,这不起作用。我想我误会了wxPanels的工作原理...希望获得任何帮助/指导
通常,paibt事件是在适当的窗口中而不是在父窗口中处理的。
无论如何,请尝试以下操作:
void MyFrame::Initialize_Draw_Input()
{
Draw_Panel = new wxPanel(this, -1); Should it be Final_Layout or "this" pointer?
Draw_Panel ->Bind(wxEVT_PAINT, &MyFrame::OnPaint, this);
}
要回答问题-父对象是this
指针,即MyFrame实例。哪个正确-您只需要适当地设置sizer。
您可以张贴尺寸编码吗?
这里有多个问题。
wxID_ANY
而不是在行中使用-1Draw_Panel = new wxPanel(this, -1);.
这样,在极不可能的情况下,将wxID_ANY更改为其他内容,您的代码将继续起作用。
Draw_Panel ->Connect(wxEVT_PAINT, wxPaintEventHandler(MyFrame::OnPaint));
您需要提供2 more parameters:userData(几乎始终为NULL
)和eventSink(几乎始终为this
)。因此,该行应如下所示:
Draw_Panel ->Connect(wxEVT_PAINT, wxPaintEventHandler(MyFrame::OnPaint),NULL,this);
MyFrame::MyFrame...
Info_Panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T(""));
Initialize_Project_Info();
Initialize_Draw_Input();
}
我假设Final_Layout在先前的问题中称为Info_Panel。但是,您可能会注意到这导致2个面板相互绘制。要解决此问题,请在[
上再添加1个sizerMyFrame::MyFrame....
wxBoxSizer* MainSizer = new wxBoxSizer(wxHORIZONTAL);
Info_Panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T(""));
Initialize_Project_Info();
Initialize_Draw_Input();
Info_Panel->Fit();
MainSizer->Add(Info_Panel,wxSizerFlags(0));
MainSizer->Add(Draw_Panel,wxSizerFlags(1).Expand());
SetSizer(MainSizer);
}
这将产生此布局:
framePanel
,但可以将其命名为任何您想要的名称。然后,framePanel
将是相框的唯一子项,其他2个面板将是framePanel
的子项。所以新的构造函数可能看起来像这样:
MyFrame::MyFrame
wxBoxSizer* MainSizer = new wxBoxSizer(wxHORIZONTAL);
framePanel = new wxPanel(this, wxID_ANY);
Info_Panel = new wxPanel(framePanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T(""));
Initialize_Project_Info();
Initialize_Draw_Input();
Info_Panel->Fit();
MainSizer->Add(Info_Panel,wxSizerFlags(0));
MainSizer->Add(Draw_Panel,wxSizerFlags(1).Expand());
framePanel->SetSizer(MainSizer);
}
并且您还应该更改Draw_Panel
的定义,使其具有新的父对象,如下所示:
Draw_Panel = new wxPanel(framePanel, wxID_ANY);
最后这给出了这个布局:
这就是为什么您对上一个问题的答案都包含了该部分
虽然由于“ TAB遍历”和操作系统的典型背景功能,您可以直接将控件放置在wxFrame中,所以最好使用wxPanel。