<div dir="ltr">At the risk of sending duplicate information, and you should prefer Matthias' responses as he is far more experienced, but one idea is to place all drawing code under the canvas class definition. Then the button callback should invoke that class' new drawing method. This keeps the actual drawing code within the canvas which is one of its main purposes. The button just says "do it".<br><div><br></div><div><div>#lang racket/gui</div><div><br></div><div>(define frame (new frame%</div><div>                   [label "Example"]</div><div>                   [width 300]</div><div>                   [height 300]))</div><div>(define top-canvas (new (class canvas% (super-new [parent frame])</div><div>                          (define dc (send this get-dc))</div><div>                          </div><div>                          (define/public (draw-something-else)</div><div>                            (send dc draw-rectangle</div><div>                                  50 50</div><div>                                  80 80))</div><div>                          </div><div>                          (define/override (on-paint)</div><div>                            (send dc draw-rectangle</div><div>                                  0  10   ; Top-left at (0, 10), 10 pixels down from top-left</div><div>                                  30 10) ; 30 pixels wide and 10 pixels high</div><div>                            (send dc draw-line</div><div>                                  0 0    ; Start at (0, 0), the top-left corner</div><div>                                  30 30) ; and draw to (30, 30), the bottom-right corner</div><div>                            (send dc draw-line</div><div>                                  0 30   ; Start at (0, 30), the bottom-left corner</div><div>                                  30 0)  ; and draw to (30, 0), the top-right corner</div><div>                            ))))</div><div><br></div><div>(define button1 (new button%</div><div>                     [label "A Box"]</div><div>                     [parent frame]</div><div>                     [callback (λ (b e)</div><div>                                 (send top-canvas draw-something-else))]))</div><div><br></div><div>(define button2 (new button%</div><div>                     [label "Erase"]</div><div>                     [parent frame]</div><div>                     [callback (λ (b e)</div><div>                                 (send top-canvas refresh))]))</div><div><br></div><div>(send frame show #t)</div></div><div><br></div><div>Refresh clears the canvas and the does on-paint again, so on-paint is sort of your default view.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 1, 2014 at 10:16 PM, Chris Wright <span dir="ltr"><<a href="mailto:cawright.99@gmail.com" target="_blank">cawright.99@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div>Thanks Matthias and Sean<br></div><br></div>It's often helpful when people asking questions ask them clearly ! :)<br></div>I'll now attempt a clarification...<br><br>say I have a button in the window, and when that button is pressed, I want to draw on the canvas - and later, another button is pressed, and I might want to draw something else somewhere else on the canvas.<br><br>I think I'm wanting to get hold of the dc outside of the definition of on-paint in the initialisation code <br><br></div>cheers and thanks again<br><br>Chris<br></div><div class="gmail_extra"><div><div class="h5"><br><div class="gmail_quote">On 2 October 2014 11:57, Matthias Felleisen <span dir="ltr"><<a href="mailto:matthias@ccs.neu.edu" target="_blank">matthias@ccs.neu.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Does this help?<br>
<span><br>
#lang racket/gui<br>
<br>
(define frame<br>
  (new frame%<br>
       [label "Example"]<br>
       [width 300]<br>
       [height 300]))<br>
<br>
(define top-canvas<br>
</span>  (new (class canvas%<br>
         (inherit get-dc)<br>
         (super-new [parent frame])<br>
         (define/override (on-paint)<br>
           (define dc (get-dc))<br>
<span>           (send dc draw-rectangle<br>
                 0  10   ; Top-left at (0, 10), 10 pixels down from top-left<br>
                 30 10) ; 30 pixels wide and 10 pixels high<br>
           (send dc draw-line<br>
                 0 0    ; Start at (0, 0), the top-left corner<br>
                 30 30) ; and draw to (30, 30), the bottom-right corner<br>
           (send dc draw-line<br>
                 0 30   ; Start at (0, 30), the bottom-left corner<br>
                 30 0)  ; and draw to (30, 0), the top-right corner<br>
</span>           ))))<br>
<br>
(send frame show #t)<br>
<div><div><br>
<br>
<br>
<br>
On Oct 1, 2014, at 9:51 PM, Chris Wright wrote:<br>
<br>
> I would like to draw on a canvas in a window at various times during program execution.<br>
> My first attempt was to combine two examples:<br>
><br>
> #lang racket/gui<br>
><br>
> (define frame (new frame%<br>
>                    [label "Example"]<br>
>                    [width 300]<br>
>                    [height 300]))<br>
> (define top-canvas (new canvas% [parent frame]))<br>
><br>
> (send frame show #t)<br>
><br>
> (define dc (send top-canvas get-dc))<br>
><br>
> (send dc draw-rectangle<br>
>       0  10   ; Top-left at (0, 10), 10 pixels down from top-left<br>
>       30 10) ; 30 pixels wide and 10 pixels high<br>
> (send dc draw-line<br>
>       0 0    ; Start at (0, 0), the top-left corner<br>
>       30 30) ; and draw to (30, 30), the bottom-right corner<br>
> (send dc draw-line<br>
>       0 30   ; Start at (0, 30), the bottom-left corner<br>
>       30 0)  ; and draw to (30, 0), the top-right corner<br>
><br>
><br>
><br>
> The cross and box are drawn, but "instantly" over-written by a blank canvas. I suppose this is because on-paint is triggered? (not sure by what..)<br>
> If I put the (send frame...) form at the end of the code, the cross and box aren't seen.<br>
><br>
> I am sure this is due to me not understanding the model properly - I'd be grateful for some help...<br>
><br>
> many thanks<br>
><br>
> Chris<br>
</div></div>> ____________________<br>
>  Racket Users list:<br>
>  <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br>
</blockquote></div><br><br clear="all"><br></div></div><span class="HOEnZb"><font color="#888888">-- <br>A/Prof Chris Wright<br>MBBS, FRACP, FCICM, GradDipiSc(Physics)<br>Academic Coordinator, Years III - V Central MBBS<br>Intensive Care Specialist<br>Faculty of Medicine, Nursing and Health Sciences,<br>Monash University<br>Clayton VIC
</font></span></div>
</blockquote></div><br></div>