Page 1 of 1

WxPaintHandler

Posted: Thu Aug 01, 2019 6:15 pm
by gillp28
I wanted to add the wxPaintDC to a panel and I am getting errors with it. I have added the EVT_PAINT Handler class as well.

Code: Select all

/***************************************************************
 * Name:      MachineLearningLinkerMain.cpp
 * Purpose:   Code for Application Frame
 * Author:     ()
 * Created:   2019-07-27
 * Copyright:  ()
 * License:
 **************************************************************/

#include "MachineLearningLinkerMain.h"
#include <wx/msgdlg.h>

 //(*InternalHeaders(MachineLearningLinkerFrame)
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/listctrl.h>
#include <boost/property_tree/ptree.hpp>
#include "boost\foreach.hpp"
#include "boost\property_tree\json_parser.hpp"
#include <boost/property_tree/xml_parser.hpp>
#include <boost/algorithm/string.hpp>
#include <wx/sizer.h>
#include <wx/treebase.h>
#include <unordered_map>
#include <array>
#include <wx/treectrl.h>
#include <wx/dcclient.h>

//*)

//helper functions
enum wxbuildinfoformat {
	short_f, long_f
};

wxString wxbuildinfo(wxbuildinfoformat format)
{
	wxString wxbuild(wxVERSION_STRING);

	if (format == long_f)
	{
#if defined(__WXMSW__)
		wxbuild << _T("-Windows");
#elif defined(__UNIX__)
		wxbuild << _T("-Linux");
#endif

#if wxUSE_UNICODE
		wxbuild << _T("-Unicode build");
#else
		wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
	}

	return wxbuild;
}

//(*IdInit(MachineLearningLinkerFrame)
const long MachineLearningLinkerFrame::ID_MENUITEM1 = wxNewId();
const long MachineLearningLinkerFrame::idMenuAbout = wxNewId();
const long MachineLearningLinkerFrame::ID_STATUSBAR1 = wxNewId();
//*)

BEGIN_EVENT_TABLE(MachineLearningLinkerFrame, wxFrame)
//(*EventTable(MachineLearningLinkerFrame)
	EVT_PAINT(MachineLearningLinkerFrame::on_paint)
//*)
END_EVENT_TABLE()

MachineLearningLinkerFrame::MachineLearningLinkerFrame(wxWindow* parent, wxWindowID id)
{
	//(*Initialize(MachineLearningLinkerFrame)
	wxMenu* Menu1;
	wxMenu* Menu2;
	wxMenuBar* MenuBar1;
	wxMenuItem* MenuItem1;
	wxMenuItem* MenuItem2;
	wxPanel* mainPanel; 
	wxBoxSizer* verticalSizer = new wxBoxSizer(wxVERTICAL);
	wxBoxSizer* horizontalSizer = new wxBoxSizer(wxHORIZONTAL);
	wxPaintDC* wxPaint; 

	Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("wxID_ANY"));
	SetClientSize(wxSize(529, 450));
	mainPanel = new wxPanel(this, wxID_ANY); 
	wxPaint = new wxPaintDC(mainPanel); 
	mainPanel->SetSizer(verticalSizer);
	verticalSizer->Add(horizontalSizer, 1, wxEXPAND | wxALL, 10);


	MenuBar1 = new wxMenuBar();
	Menu1 = new wxMenu();
	MenuItem1 = new wxMenuItem(Menu1, ID_MENUITEM1, _("Quit\tAlt-F4"), _("Quit the application"), wxITEM_NORMAL);
	Menu1->Append(MenuItem1);
	MenuBar1->Append(Menu1, _("&File"));
	Menu2 = new wxMenu();
	MenuItem2 = new wxMenuItem(Menu2, idMenuAbout, _("About\tF1"), _("Show info about this application"), wxITEM_NORMAL);
	Menu2->Append(MenuItem2);
	MenuBar1->Append(Menu2, _("Help"));
	SetMenuBar(MenuBar1);
	StatusBar1 = new wxStatusBar(this, ID_STATUSBAR1, 0, _T("ID_STATUSBAR1"));
	int __wxStatusBarWidths_1[1] = { -1 };
	int __wxStatusBarStyles_1[1] = { wxSB_NORMAL };
	StatusBar1->SetFieldsCount(1, __wxStatusBarWidths_1);
	StatusBar1->SetStatusStyles(1, __wxStatusBarStyles_1);
	SetStatusBar(StatusBar1);

	wxListCtrl* list;
	list = new wxListCtrl(mainPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_LIST);
	wxTreeCtrl* treeList; 
	treeList = new wxTreeCtrl(mainPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize); 
	treeList->AddRoot("Pavneet"); 
	horizontalSizer->Add(list, 2, wxEXPAND | wxALL, 10); 
	horizontalSizer->Add(treeList, 1, wxEXPAND | wxALL, 10);
	boost::property_tree::ptree pt1;
	boost::property_tree::ptree pt2;
	boost::property_tree::read_xml("C:/Users/pavne/Downloads/model_meta_data.xml", pt1);	

	

	std::string text = pt1.get_child("ModelMetaData").get_child("categories").get_value<std::string>();
	std::vector<std::string> results;

	

	
	boost::split(results, text, [](char c) 
		{
			return c == ','; 
		}
	);


	for (int i = 0; i < 3; i++)
	{
		list->InsertItem(i, results[i]);
	}

	

	Connect(ID_MENUITEM1, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)& MachineLearningLinkerFrame::OnQuit);
	Connect(idMenuAbout, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)& MachineLearningLinkerFrame::OnAbout);
	//*)
}

MachineLearningLinkerFrame::~MachineLearningLinkerFrame()
{
	//(*Destroy(MachineLearningLinkerFrame)
	//*)
}

void MachineLearningLinkerFrame::OnQuit(wxCommandEvent& event)
{
	Close();
}

void MachineLearningLinkerFrame::OnAbout(wxCommandEvent& event)
{
	wxString msg = wxbuildinfo(long_f);
	wxMessageBox(msg, _("Welcome to..."));
}

void MachineLearningLinkerFrame::on_paint(wxPaintEvent& WXUNUSED(event))
{

}

Re: WxPaintHandler

Posted: Thu Aug 01, 2019 7:23 pm
by gillp28
I have gotten rid of the error. Anytime I try to draw something on the panel it is not visible.

Code: Select all

/***************************************************************
 * Name:      MachineLearningLinkerMain.cpp
 * Purpose:   Code for Application Frame
 * Author:     ()
 * Created:   2019-07-27
 * Copyright:  ()
 * License:
 **************************************************************/

#include "MachineLearningLinkerMain.h"
#include <wx/msgdlg.h>

 //(*InternalHeaders(MachineLearningLinkerFrame)
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/listctrl.h>
#include <boost/property_tree/ptree.hpp>
#include "boost\foreach.hpp"
#include "boost\property_tree\json_parser.hpp"
#include <boost/property_tree/xml_parser.hpp>
#include <boost/algorithm/string.hpp>
#include <wx/sizer.h>
#include <wx/treebase.h>
#include <unordered_map>
#include <array>
#include <wx/treectrl.h>
#include <wx/dcclient.h>

//*)

//helper functions
enum wxbuildinfoformat {
	short_f, long_f
};

wxString wxbuildinfo(wxbuildinfoformat format)
{
	wxString wxbuild(wxVERSION_STRING);

	if (format == long_f)
	{
#if defined(__WXMSW__)
		wxbuild << _T("-Windows");
#elif defined(__UNIX__)
		wxbuild << _T("-Linux");
#endif

#if wxUSE_UNICODE
		wxbuild << _T("-Unicode build");
#else
		wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
	}

	return wxbuild;
}

//(*IdInit(MachineLearningLinkerFrame)
const long MachineLearningLinkerFrame::ID_MENUITEM1 = wxNewId();
const long MachineLearningLinkerFrame::idMenuAbout = wxNewId();
const long MachineLearningLinkerFrame::ID_STATUSBAR1 = wxNewId();
//*)

BEGIN_EVENT_TABLE(MachineLearningLinkerFrame, wxFrame)
//(*EventTable(MachineLearningLinkerFrame)
	EVT_PAINT(MachineLearningLinkerFrame::on_paint)
//*)
END_EVENT_TABLE()

MachineLearningLinkerFrame::MachineLearningLinkerFrame(wxWindow* parent, wxWindowID id)
{
	//(*Initialize(MachineLearningLinkerFrame)
	wxMenu* Menu1;
	wxMenu* Menu2;
	wxMenuBar* MenuBar1;
	wxMenuItem* MenuItem1;
	wxMenuItem* MenuItem2;
	wxPanel* mainPanel; 
	wxBoxSizer* verticalSizer = new wxBoxSizer(wxVERTICAL);
	wxBoxSizer* horizontalSizer = new wxBoxSizer(wxHORIZONTAL);
	wxClientDC* wxPaint; 

	Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("wxID_ANY"));
	SetClientSize(wxSize(529, 450));
	mainPanel = new wxPanel(this, wxID_ANY,wxPoint(0,0),wxSize(500,500)); 
	wxPaint = new wxClientDC(mainPanel); 
	//mainPanel->SetSizer(verticalSizer);
	//verticalSizer->Add(horizontalSizer, 1, wxEXPAND | wxALL, 10);


	MenuBar1 = new wxMenuBar();
	Menu1 = new wxMenu();
	MenuItem1 = new wxMenuItem(Menu1, ID_MENUITEM1, _("Quit\tAlt-F4"), _("Quit the application"), wxITEM_NORMAL);
	Menu1->Append(MenuItem1);
	MenuBar1->Append(Menu1, _("&File"));
	Menu2 = new wxMenu();
	MenuItem2 = new wxMenuItem(Menu2, idMenuAbout, _("About\tF1"), _("Show info about this application"), wxITEM_NORMAL);
	Menu2->Append(MenuItem2);
	MenuBar1->Append(Menu2, _("Help"));
	SetMenuBar(MenuBar1);
	StatusBar1 = new wxStatusBar(this, ID_STATUSBAR1, 0, _T("ID_STATUSBAR1"));
	int __wxStatusBarWidths_1[1] = { -1 };
	int __wxStatusBarStyles_1[1] = { wxSB_NORMAL };
	StatusBar1->SetFieldsCount(1, __wxStatusBarWidths_1);
	StatusBar1->SetStatusStyles(1, __wxStatusBarStyles_1);
	SetStatusBar(StatusBar1);

	wxPaint->DrawText(wxT("Testing"), 40, 60);

	// draw a circle
	wxPaint->SetBrush(*wxGREEN_BRUSH); // green filling
	wxPaint->SetPen(wxPen(wxColor(255, 0, 0), 5)); // 5-pixels-thick red outline
	wxPaint->DrawCircle(wxPoint(200, 100), 25 /* radius */);
	//wxListCtrl* list;
	//list = new wxListCtrl(mainPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_LIST);
	//wxTreeCtrl* treeList; 
	//treeList = new wxTreeCtrl(mainPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize); 
	//treeList->AddRoot("Pavneet"); 
	//horizontalSizer->Add(list, 2, wxEXPAND | wxALL, 10); 
	//horizontalSizer->Add(treeList, 1, wxEXPAND | wxALL, 10);
	boost::property_tree::ptree pt1;
	boost::property_tree::ptree pt2;
	boost::property_tree::read_xml("C:/Users/pavne/Downloads/model_meta_data.xml", pt1);	

	

	std::string text = pt1.get_child("ModelMetaData").get_child("categories").get_value<std::string>();
	std::vector<std::string> results;

	

	
	boost::split(results, text, [](char c) 
		{
			return c == ','; 
		}
	);


	for (int i = 0; i < 3; i++)
	{
		//list->InsertItem(i, results[i]);
	}

	

	Connect(ID_MENUITEM1, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)& MachineLearningLinkerFrame::OnQuit);
	Connect(idMenuAbout, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)& MachineLearningLinkerFrame::OnAbout);
	//*)
}

MachineLearningLinkerFrame::~MachineLearningLinkerFrame()
{
	//(*Destroy(MachineLearningLinkerFrame)
	//*)
}

void MachineLearningLinkerFrame::OnQuit(wxCommandEvent& event)
{
	Close();
}

void MachineLearningLinkerFrame::OnAbout(wxCommandEvent& event)
{
	wxString msg = wxbuildinfo(long_f);
	wxMessageBox(msg, _("Welcome to..."));
}

void MachineLearningLinkerFrame::on_paint(wxPaintEvent& WXUNUSED(event))
{

}


Re: WxPaintHandler

Posted: Thu Aug 01, 2019 7:25 pm
by doublemax
What kind of errors are you getting? Compliler, linker, or runtime errors?

I assume you want to draw onto "mainPanel"? Then there are a couple of issues.

Code: Select all

BEGIN_EVENT_TABLE(MachineLearningLinkerFrame, wxFrame)
//(*EventTable(MachineLearningLinkerFrame)
	EVT_PAINT(MachineLearningLinkerFrame::on_paint)
//*)
END_EVENT_TABLE()
With this entry you could only draw onto the frame. But as the whole frame is covered by other controls, you wouldn't see it. Remove that EVT_PAINT line.

Code: Select all

wxPaintDC* wxPaint; 
..
wxPaint = new wxPaintDC(mainPanel); 
This doesn't make sense at all. Creating a wxPaintDC only makes sense inside a paint event handler. Remove these.

Instead add:

Code: Select all

mainPanel->Bind(wxEVT_PAINT, &MachineLearningLinkerFrame::on_paint, this );

Then, the paint event handler:

Code: Select all

void MachineLearningLinkerFrame::on_paint(wxPaintEvent& WXUNUSED(event))
{
  // you *must* create a wxPaintDC in a paint event handler.
  wxPaintDC dc(mainPanel);
   
  // dummy drawing
  dc.SetBrush( *wxYELLOW );
  dc.DrawRect( wxRect(mainPanel->GetClientSize()) );
}

Re: WxPaintHandler

Posted: Thu Aug 01, 2019 7:35 pm
by PB
(oops I was slow and I also missed the attempt at drawing in the constructor)

What errors are you getting? Assuming on_paint() is declared in the header file, the code should compile just fine.

But you must create wxPaintDC in the event handler, even if you for some reason do not use it.

A simple painting code could look like this

Code: Select all

void MachineLearningLinkerFrame::on_paint(wxPaintEvent& WXUNUSED(event))
{
    wxPaintDC dc(this);
     const wxRect r = wxRect(dc.GetSize());

     dc.SetPen(*wxRED_PEN);
     dc.SetBrush(*wxBLUE_BRUSH);
     dc.DrawCircle(r.GetLeft() + r.GetWidth() / 2, r.GetTop() + r.GetHeight() / 2, r.GetWidth() / 2 );
}
But if you want a custom-drawn window, you usually do not paint on the frame, you use a wxPanel derived class which you then put inside the frame.

Re: WxPaintHandler

Posted: Fri Aug 02, 2019 7:35 pm
by gillp28
Thanks that works. Now I am trying to draw a point based on the mouse event and for some reason, it is not working.

Code: Select all

/***************************************************************
 * Name:      MachineLearningLinkerMain.cpp
 * Purpose:   Code for Application Frame
 * Author:     ()
 * Created:   2019-07-27
 * Copyright:  ()
 * License:
 **************************************************************/

#include "MachineLearningLinkerMain.h"
#include <wx/msgdlg.h>

 //(*InternalHeaders(MachineLearningLinkerFrame)
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/listctrl.h>
#include <boost/property_tree/ptree.hpp>
#include "boost\foreach.hpp"
#include "boost\property_tree\json_parser.hpp"
#include <boost/property_tree/xml_parser.hpp>
#include <boost/algorithm/string.hpp>
#include <wx/sizer.h>
#include <wx/treebase.h>
#include <unordered_map>
#include <array>
#include <wx/treectrl.h>
#include <wx/dcclient.h>
#include <wx/event.h>
//*)

//helper functions
enum wxbuildinfoformat {
	short_f, long_f
};

wxString wxbuildinfo(wxbuildinfoformat format)
{
	wxString wxbuild(wxVERSION_STRING);

	if (format == long_f)
	{
#if defined(__WXMSW__)
		wxbuild << _T("-Windows");
#elif defined(__UNIX__)
		wxbuild << _T("-Linux");
#endif

#if wxUSE_UNICODE
		wxbuild << _T("-Unicode build");
#else
		wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
	}

	return wxbuild;
}
wxPanel* mainPanel;

//(*IdInit(MachineLearningLinkerFrame)
const long MachineLearningLinkerFrame::ID_MENUITEM1 = wxNewId();
const long MachineLearningLinkerFrame::idMenuAbout = wxNewId();
const long MachineLearningLinkerFrame::ID_STATUSBAR1 = wxNewId();
//*)

BEGIN_EVENT_TABLE(MachineLearningLinkerFrame, wxFrame)
//(*EventTable(MachineLearningLinkerFrame)
	EVT_MOTION(MachineLearningLinkerFrame::onMouse)
//*)
END_EVENT_TABLE()

MachineLearningLinkerFrame::MachineLearningLinkerFrame(wxWindow* parent, wxWindowID id)
{
	//(*Initialize(MachineLearningLinkerFrame)
	wxMenu* Menu1;
	wxMenu* Menu2;
	wxMenuBar* MenuBar1;
	wxMenuItem* MenuItem1;
	wxMenuItem* MenuItem2;
	wxBoxSizer* verticalSizer = new wxBoxSizer(wxVERTICAL);
	wxBoxSizer* horizontalSizer = new wxBoxSizer(wxHORIZONTAL);
	

	Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("wxID_ANY"));
	SetClientSize(wxSize(529, 450));
	mainPanel = new wxPanel(this, wxID_ANY,wxPoint(0,0),wxSize(500,500)); 
	mainPanel->Bind(wxEVT_PAINT, &MachineLearningLinkerFrame::on_paint, this);
	//mainPanel->SetSizer(verticalSizer);
	//verticalSizer->Add(horizontalSizer, 1, wxEXPAND | wxALL, 10);


	MenuBar1 = new wxMenuBar();
	Menu1 = new wxMenu();
	MenuItem1 = new wxMenuItem(Menu1, ID_MENUITEM1, _("Quit\tAlt-F4"), _("Quit the application"), wxITEM_NORMAL);
	Menu1->Append(MenuItem1);
	MenuBar1->Append(Menu1, _("&File"));
	Menu2 = new wxMenu();
	MenuItem2 = new wxMenuItem(Menu2, idMenuAbout, _("About\tF1"), _("Show info about this application"), wxITEM_NORMAL);
	Menu2->Append(MenuItem2);
	MenuBar1->Append(Menu2, _("Help"));
	SetMenuBar(MenuBar1);
	StatusBar1 = new wxStatusBar(this, ID_STATUSBAR1, 0, _T("ID_STATUSBAR1"));
	int __wxStatusBarWidths_1[1] = { -1 };
	int __wxStatusBarStyles_1[1] = { wxSB_NORMAL };
	StatusBar1->SetFieldsCount(1, __wxStatusBarWidths_1);
	StatusBar1->SetStatusStyles(1, __wxStatusBarStyles_1);
	SetStatusBar(StatusBar1);


	//wxListCtrl* list;
	//list = new wxListCtrl(mainPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_LIST);
	//wxTreeCtrl* treeList; 
	//treeList = new wxTreeCtrl(mainPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize); 
	//treeList->AddRoot("Pavneet"); 
	//horizontalSizer->Add(list, 2, wxEXPAND | wxALL, 10); 
	//horizontalSizer->Add(treeList, 1, wxEXPAND | wxALL, 10);
	boost::property_tree::ptree pt1;
	boost::property_tree::ptree pt2;
	boost::property_tree::read_xml("C:/Users/pavne/Downloads/model_meta_data.xml", pt1);	

	

	std::string text = pt1.get_child("ModelMetaData").get_child("categories").get_value<std::string>();
	std::vector<std::string> results;

	

	
	boost::split(results, text, [](char c) 
		{
			return c == ','; 
		}
	);


	for (int i = 0; i < 3; i++)
	{
		//list->InsertItem(i, results[i]);
	}

	

	Connect(ID_MENUITEM1, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)& MachineLearningLinkerFrame::OnQuit);
	Connect(idMenuAbout, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)& MachineLearningLinkerFrame::OnAbout);
	Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler (MachineLearningLinkerFrame::onMouse));
	//*)
}

MachineLearningLinkerFrame::~MachineLearningLinkerFrame()
{
	//(*Destroy(MachineLearningLinkerFrame)
	//*)
}

void MachineLearningLinkerFrame::OnQuit(wxCommandEvent& event)
{
	Close();
}

void MachineLearningLinkerFrame::OnAbout(wxCommandEvent& event)
{
	wxString msg = wxbuildinfo(long_f);
	wxMessageBox(msg, _("Welcome to..."));
}

void MachineLearningLinkerFrame::on_paint(wxPaintEvent& WXUNUSED(event))
{
	wxPaintDC dc(mainPanel);
	//dc.SetBrush(*wxRED);
	//dc.DrawLine(wxPoint(10, 10), wxPoint(100, 100)); 
}

void MachineLearningLinkerFrame::onMouse(wxMouseEvent& event)
{
	if (event.Dragging())
	{
		wxPaintDC dc(mainPanel);
		wxPen pen(*wxRED, 1); // red pen of width 1
		dc.SetPen(pen);
		dc.DrawPoint(event.GetPosition());
		dc.SetPen(wxNullPen);
	}
}

Re: WxPaintHandler

Posted: Fri Aug 02, 2019 7:42 pm
by doublemax

Code: Select all

void MachineLearningLinkerFrame::onMouse(wxMouseEvent& event)
{
	if (event.Dragging())
	{
		wxPaintDC dc(mainPanel);
It's not that easy.

First of all, you can create a wxPaintDC *only* inside a paint event handler. If you wanted to draw directly onto the window, you could use wxClientDC. But: Everything you draw there will be overdrawn by the next "regular" paint event, so it doesn't make sense to do it this way. If you want to create a permanent drawing, you need to draw into a persistent bitmap, and then in the paint event handler, you just draw that bitmap.

Re: WxPaintHandler

Posted: Fri Aug 02, 2019 8:11 pm
by ONEEYEMAN
Which is actually wxOverlay...

Thank you.

Re: WxPaintHandler

Posted: Fri Aug 02, 2019 8:28 pm
by PB
In addition to what doublemax said, you could consider storing all the information and drawing it in the wxPaintEvent handler. Bitmap may not be ideal if the window can be resized.

FWIW, the simple code here draws lines created with the mouse
viewtopic.php?t=44596#p184274