Hello,
I want to draw on a wxPanel, which is located next to another one containing GUI-elements. Both panels are assigned to a sizer. Now my question is: How do I implement the class for the panel I want to draw on, correctly. I have had a look at various examples, but I didn't fully understand, how the declaration of the panel I want to draw on works.
I hope, anyone can help me with this issue - thanks in advance!
Best,
Felix
How can I draw on a wxPanel Topic is solved
Re: How can I draw on a wxPanel
When posting any question, please be more concrete about what your problem is.
https://wiki.wxwidgets.org/Drawing_on_a_panel_with_a_DC
https://wiki.wxwidgets.org/Drawing_on_a_panel_with_a_DC
Use the source, Luke!
Re: How can I draw on a wxPanel
Hello,
thank you for your quick reply. I will try to be more concrete, when describing my problem(s) in the future.
I have created a (somewhat messy) example, only containing the panels and a drawPane and added a comment to my code, trying to describe my problem in a better way.
I hope, my problem is now a little bit more clear.
thank you for your quick reply. I will try to be more concrete, when describing my problem(s) in the future.
I have created a (somewhat messy) example, only containing the panels and a drawPane and added a comment to my code, trying to describe my problem in a better way.
Code: Select all
#include "wx/wx.h"
#include "wx/sizer.h"
class BasicPane : public wxPanel
{
public:
BasicPane(wxFrame* parent);
void paintEvent(wxPaintEvent& e);
void paintNow();
void render(wxDC& dc);
DECLARE_EVENT_TABLE()
};
class MyApp : public wxApp
{
public:
bool OnInit();
wxFrame* frame;
BasicPane* drawPane;
public:
};
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
wxBoxSizer* s1 = new wxBoxSizer(wxHORIZONTAL);
wxPanel* panel1 = new wxPanel(this, wxID_ANY);
wxPanel* panel2 = new wxPanel(this, wxID_ANY);
};
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
auto frame = new MyFrame("HELLO wxDC", wxDefaultPosition, wxDefaultSize);
drawPane = new BasicPane((wxFrame*)frame);
frame->Show();
return true;
}
BEGIN_EVENT_TABLE(BasicPane, wxPanel)
EVT_PAINT(BasicPane::paintEvent)
END_EVENT_TABLE()
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(nullptr, wxID_ANY, title, pos, size)
{
panel1->SetBackgroundColour(wxColor(255, 1, 0));
panel2->SetBackgroundColour(wxColor(2, 155, 0));
//I want to draw something on panel1; panel2 contains the GUI elements
s1->Add(panel1, 1, wxEXPAND);
s1->Add(panel2, 1, wxEXPAND);
this->SetSizerAndFit(s1);
}
BasicPane::BasicPane(wxFrame* parent) : wxPanel(parent) {
}
void BasicPane::paintEvent(wxPaintEvent& evt) {
wxPaintDC dc(this);
render(dc);
}
void BasicPane::paintNow() {
wxClientDC dc(this);
render(dc);
}
void BasicPane::render(wxDC& dc) {
dc.DrawText(wxT("Test"), 40, 60);
}
Re: How can I draw on a wxPanel
You can't just draw something on a panel and expect it to stay there forever. The ways it works is that you need to draw the content of the panel when ever the OS requests it. You do that by catching the wxEVT_PAINT event (for that panel!) and do the drawing in the paint event handler.
Does this appear on the panel?
This stuff in the class declaration doesn't make any sense. Put it into the constructor.
This panel is not part of the sizer structure, so it will probably be covered by the two other panels.
Code: Select all
dc.DrawText(wxT("Test"), 40, 60);
Code: Select all
wxBoxSizer* s1 = new wxBoxSizer(wxHORIZONTAL);
wxPanel* panel1 = new wxPanel(this, wxID_ANY);
wxPanel* panel2 = new wxPanel(this, wxID_ANY);
Code: Select all
drawPane = new BasicPane((wxFrame*)frame);
Use the source, Luke!
Re: How can I draw on a wxPanel
Hello and thank you for your reply and suggestions.
Whenever I want to add the "drawPane" directly to the sizer s1, Microsoft Visual Studio tells me, that the identifier "drawPane" isn't identified. So my question in this case would be how I could add it to the sizer structure correctly.
Thank you for help!
Basically, yes. When I don't have the other two panels and only the "drawPane", the text is displayed. Right now, the two colored panels take up the whole space in the window, while the "drawPane" is just a little grey rectangle in the top left corner.doublemax wrote: ↑Tue Aug 24, 2021 5:45 pmDoes this appear on the panel?Code: Select all
dc.DrawText(wxT("Test"), 40, 60);
So my problem with this is the following:doublemax wrote: ↑Tue Aug 24, 2021 5:45 pmThis panel is not part of the sizer structure, so it will probably be covered by the two other panels.Code: Select all
drawPane = new BasicPane((wxFrame*)frame);
Code: Select all
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(nullptr, wxID_ANY, title, pos, size)
{
//other code...
s1->Add(panel1, 1, wxEXPAND);
s1->Add(panel2, 1, wxEXPAND);
s1->Add(drawPane, 1, wxEXPAND);
this->SetSizerAndFit(s1);
}
Thank you for help!
Re: How can I draw on a wxPanel
You created "drawPane" inside MyApp::OnInit, therefore it's unknown inside MyFrame. Move the construction of "drawPane" to the MyFrame constructor.Whenever I want to add the "drawPane" directly to the sizer s1, Microsoft Visual Studio tells me, that the identifier "drawPane" isn't identified. So my question in this case would be how I could add it to the sizer structure correctly.
Here's another minimal sample for you to study
Code: Select all
#include <wx/wx.h>
class MyApp : public wxApp
{
public:
virtual bool OnInit();
};
wxIMPLEMENT_APP(MyApp);
class CustomPanel : public wxPanel
{
public:
CustomPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE)
{
Bind(wxEVT_PAINT, &CustomPanel::OnPaint, this);
SetBackgroundStyle(wxBG_STYLE_PAINT);
};
void OnPaint(wxPaintEvent &event)
{
wxPaintDC dc(this);
dc.SetBackground(*wxYELLOW);
dc.Clear();
dc.DrawText( wxString::Format("size: %d x %d", GetClientSize().x, GetClientSize().y), 10, 10);
};
};
class MyFrame : public wxFrame
{
public:
MyFrame() : wxFrame(NULL, wxID_ANY, "Minimal Sample")
{
wxBoxSizer *mainSizer = new wxBoxSizer(wxHORIZONTAL);
CustomPanel *panel1 = new CustomPanel(this);
mainSizer->Add(panel1, 1, wxEXPAND, 0);
wxPanel *panel2 = new wxPanel(this, wxID_ANY);
panel2->SetBackgroundColour(*wxBLUE);
mainSizer->Add(panel2, 1, wxEXPAND, 0);
SetSizer(mainSizer);
};
};
bool MyApp::OnInit()
{
MyFrame* frame = new MyFrame();
frame->Show(true);
return true;
}
Use the source, Luke!