wxPaintDC graph Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
StaticShell
Experienced Solver
Experienced Solver
Posts: 65
Joined: Tue Sep 22, 2009 9:19 am
Location: Golden Saucer

wxPaintDC graph

Post by StaticShell »

Hello,

I decided to attempt to draw my own graph with widgets, but I am having some trouble drawing to my frame.

below I have re-created my project with just the key features included to show more clearly, the draw function is taken from the widgets example archieve but when this class is called the frame/window is shown with no rectangle?

Code: Select all

#include "BatteryHistory.h"

BEGIN_EVENT_TABLE(BatteryHistory, wxFrame)

    EVT_BUTTON(ID_EXIT, BatteryHistory::exitEvt)

END_EVENT_TABLE()

BatteryHistory::BatteryHistory(const wxString& title, const wxPoint &position, const wxSize& size, long style)
       : wxFrame(NULL, ID_BATTERY, title, wxDefaultPosition, wxSize(380,320))
{


    //Frame setup
    mainFrameSizer = new wxBoxSizer(wxVERTICAL);
    this->SetSizer(mainFrameSizer);
    this->SetAutoLayout(TRUE);
    this->SetBackgroundColour(wxColour(255, 255, 255));
    this->SetIcon(wxICON(sample));


   //Draw Graph
   wxPaintDC dc(this);
   drawGraph(dc);


    Center();
}




/////////////////////////////////////////////////////////////
//destructor
/////////////////////////////////////////////////////////////
BatteryHistory::~BatteryHistory()
{}





/////////////////////////////////////////////////////////////
//Draw Graph
/////////////////////////////////////////////////////////////
void BatteryHistory::drawGraph(wxDC& dc)
{
    dc.SetPen(*wxBLACK_PEN);
    dc.SetBrush(*wxRED_BRUSH);

    // Get window dimensions
    wxSize sz = GetClientSize();

    // Our rectangle dimensions
    wxCoord w = 100, h = 50;

    // Center the rectangle on the window, but never
    // draw at a negative position.
    int x = wxMax(0, (sz.x - w)/2);
    int y = wxMax(0, (sz.y - h)/2);

    wxRect rectToDraw(x, y, w, h);

    dc.DrawRectangle(rectToDraw);
}

if anyone can please show me what noob mistake I have made, and why this DrawRectangle method wont actually draw anything to my window, currently it just shows blank.


Thank you for any help in advance! :roll:
Romas
I live to help wx-kind
I live to help wx-kind
Posts: 176
Joined: Mon Jun 16, 2008 11:07 am
Location: Kaunas

Post by Romas »

wxPaintDC should be constructed in OnPaint event. You should call your drawGraph function from this event.
Everything requires a line of code.
dlchnr
I live to help wx-kind
I live to help wx-kind
Posts: 188
Joined: Tue Jan 27, 2009 6:45 pm
Location: Germany
Contact:

Post by dlchnr »

Hello,

I do such drawings inside the corressponding OnPaint handler - called by the wxPaintEvent (below an example, most of the
code is specific to my applicaion), while a function, which
corresponds with your drawGraph will only call wxWindow::Update() / wxWindow::Refresh().
If your drawing should be recreated, after your window
was iconized or hidden by another window, this is the correct way, I think.

Code: Select all

void cModelWindow::OnPaint(wxPaintEvent& event) {
wxPaintDC dc(this);
wxPen conPen(*wxGREEN, 3);         

  if (pcModel()->SizeModel()) {
    for (vector<cItemSet>::iterator it = pcModel()->ItemListIterator(0);it!=pcModel()->ItemListIterator();++it) {
    cItem& Item = it->GetItem();
      if (Item.IsNode()) {
        for (int i=1; i<=4; i++) {
        cConnection& Con = Item.GetCon(i);
          if (Con.ConInt()) {
            if (Con.ConExt()) {
            cItem& CounterItem = pcModel()->ItemListIterator(Con.ItemIndex())->GetItem();
            cConnection& CounterCon = CounterItem.GetCon(Con.ConExt());
              if (!((CounterCon.ConExt()==i) && (CounterCon.ItemIndex()==Item.GetIndex()))) {
                Con.ConExt(0);
                Con.ItemIndex(0);
                Item.Modified(1);
                wxMessageBox(_T("Paint: Not fitting Connection!"));
              } else {
              cItemView& ItemView = it->GetItemView();
              cItemView& CounterItemView = pcModel()->ItemListIterator(Con.ItemIndex())->GetItemView();
              cDiamonds* pSource = ItemView.GetCon(i).pcDiamonds();
              cDiamonds* pTarget = CounterItemView.GetCon(Con.ConExt()).pcDiamonds();
              wxPoint Source = pSource->PosConPoint();
              wxPoint Target = pTarget->PosConPoint();
                dc.SetPen(conPen);
                dc.DrawLine(Source.x, Source.y, Target.x, Target.y);
              }
            }
          } else {
            if (Con.ConExt() || Con.ItemIndex()) {
              Con.ConExt(0);
              Con.ItemIndex(0);
              Item.Modified(1);
              wxMessageBox(_T("Paint: ConExt() without ConInt()!"));
            }
          }
        }
      }
    }
  }
}
dlchnr
I live to help wx-kind
I live to help wx-kind
Posts: 188
Joined: Tue Jan 27, 2009 6:45 pm
Location: Germany
Contact:

Post by dlchnr »

Romas has overtook me in writing :D

Of cource you can pack your drawing inside a function and
call it from the OnPaint handler - the update() / refresh()
function has to be executed in your code, where you call
drawGraph in the moment.
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

It's hard to tell with bits of code only;
1) never create a wxPaintDC outside of paint events (like you do in the constructor)
2) do you register to the paint event? This is not visible in the code you posted. Of course it won't work if you didn't

Also see http://wiki.wxwidgets.org/Drawing_on_a_panel_with_a_DC
"Keyboard not detected. Press F1 to continue"
-- Windows
StaticShell
Experienced Solver
Experienced Solver
Posts: 65
Joined: Tue Sep 22, 2009 9:19 am
Location: Golden Saucer

Post by StaticShell »

Good Morning guys,

sorry for my late repy, but thanks for your help so far, sorry to say im still abit confused :?

the code I shown in first post, I was wanting this draw to happen without a mouse event, basically, when this class is called from another, for example:

Code: Select all

void mainclass::OnBatteryHistoryClick(wxCommandEvent& event)
{
    BatteryHistory *simple = new BatteryHistory("Battery");
    simple->Show(true);
}



I wanted the batteryHistory class to automatically draw up a grid. so how would I get around this event?


sorry if this sounds confusing but trying to understand this draw for first time

:oops:

angain I really appreciate any help[/code]
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax »

i think the point you're missing is that you need to draw your graph every time the system sends a paint event, not just once.

That's why you need to do your drawing inside a paint event handler. Check the link Auria posted and go from there.

And here's another tutorial about drawing:
http://zetcode.com/tutorials/wxwidgetstutorial/gdi/
Use the source, Luke!
StaticShell
Experienced Solver
Experienced Solver
Posts: 65
Joined: Tue Sep 22, 2009 9:19 am
Location: Golden Saucer

Post by StaticShell »

My apologies Auria and Doublemax, I completely overlooked that.

I understand now and again thank you for all you rhelp, you have made it so much clearer to me :)

Thank You! :D
Post Reply