SetFocus() on canvas not working?

Please support our Python advertiser: Programming Forums - DaniWeb Sister Site
Reply

Join Date: Aug 2008
Posts: 29
Reputation: artemis_f is an unknown quantity at this point 
Solved Threads: 0
artemis_f artemis_f is offline Offline
Light Poster

SetFocus() on canvas not working?

 
0
  #1
Jul 18th, 2009
1. I have an OGLCanvas with shapes on it
2. Double clicking a shape will open up a wx.MiniFrame where the user can do certain things
3. After OK is clicked or the frame is destroyed I would like the "focus" to shift back to the canvas so that without actually having to do a mouse click I can immediately start using the keyboard keys to perform actions on the canvas
4. Except where do I call the SetFocus() so that the focus successfully passes back to the parent of the miniframe?

I have tried several variations of SetFocus, SetFocusIgnoringChildren and SetFocusFromKbd both after the self.Destroy() and just before it but nothing works which leads me to conclude that there is some piece of logic that I am missing. Is there no way I can pass the focus back to the parent after the mini frame is closed??

Any advice is appreciated...
Reply With Quote Quick reply to this message  
Join Date: Oct 2006
Posts: 2,279
Reputation: sneekula has a spectacular aura about sneekula has a spectacular aura about 
Solved Threads: 176
sneekula's Avatar
sneekula sneekula is offline Offline
Nearly a Posting Maven

Re: SetFocus() on canvas not working?

 
0
  #2
Jul 18th, 2009
You can use Hide() and Show() as explained here:
  1. # create two frames with wxFrame, only one is showing
  2.  
  3. import wx
  4.  
  5. class Frame1(wx.Frame):
  6. def __init__(self, parent, mytitle):
  7. wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle)
  8. self.SetBackgroundColour("green")
  9. # pass frame1 to frame2 as instance self
  10. self.frame2 = Frame2(None, 'Frame1', self)
  11.  
  12. # create input widgets
  13. self.button1 = wx.Button(self, wx.ID_ANY, label='Frame2')
  14. self.button2 = wx.Button(self, wx.ID_ANY, label='Button2')
  15. self.button3 = wx.Button(self, wx.ID_ANY, label='Button3')
  16. # bind mouse event to an action
  17. self.button1.Bind(wx.EVT_BUTTON, self.button1Click)
  18.  
  19. # use a box sizer to lay out widgets
  20. sizer_v = wx.BoxSizer(wx.VERTICAL)
  21. # Add(widget, proportion, flag, border)
  22. sizer_v.Add(self.button1, 0, flag=wx.ALL, border=10)
  23. sizer_v.Add(self.button2, 0, flag=wx.ALL, border=10)
  24. sizer_v.Add(self.button3, 0, flag=wx.ALL, border=10)
  25. self.SetSizer(sizer_v)
  26.  
  27. # size the frame so all the widgets fit
  28. self.Fit()
  29.  
  30. def button1Click(self, event):
  31. """button1 has been left clicked"""
  32. # self is instance frame1
  33. self.Hide()
  34. self.frame2.Show()
  35.  
  36.  
  37. class Frame2(wx.Frame):
  38. def __init__(self, parent, mytitle, frame1):
  39. wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle)
  40. self.SetBackgroundColour("brown")
  41. self.frame1 = frame1
  42.  
  43. # create input widgets
  44. self.button1 = wx.Button(self, wx.ID_ANY, label='Frame1')
  45. self.button2 = wx.Button(self, wx.ID_ANY, label='Button2')
  46. self.button3 = wx.Button(self, wx.ID_ANY, label='Button3')
  47. # bind mouse event to an action
  48. self.button1.Bind(wx.EVT_BUTTON, self.button1Click)
  49. # responds to exit symbol x on frame2 title bar
  50. self.Bind(wx.EVT_CLOSE, self.button1Click)
  51.  
  52. # use a box sizer to lay out widgets
  53. sizer_v = wx.BoxSizer(wx.VERTICAL)
  54. # Add(widget, proportion, flag, border)
  55. sizer_v.Add(self.button1, 0, flag=wx.ALL, border=10)
  56. sizer_v.Add(self.button2, 0, flag=wx.ALL, border=10)
  57. sizer_v.Add(self.button3, 0, flag=wx.ALL, border=10)
  58. self.SetSizer(sizer_v)
  59.  
  60. # size the frame so all the widgets fit
  61. self.Fit()
  62.  
  63. def button1Click(self, event):
  64. """button1 has been left clicked"""
  65. # self is instance frame2
  66. self.Hide()
  67. self.frame1.Show()
  68.  
  69.  
  70. app = wx.App(0)
  71. # create a MyFrame instance and show the frame
  72. frame1 = Frame1(None, 'Frame1')
  73. frame1.Show()
  74. app.MainLoop()
No one died when Clinton lied.
Reply With Quote Quick reply to this message  
Join Date: Aug 2008
Posts: 29
Reputation: artemis_f is an unknown quantity at this point 
Solved Threads: 0
artemis_f artemis_f is offline Offline
Light Poster

Re: SetFocus() on canvas not working?

 
0
  #3
Jul 18th, 2009
Thanks for your reply sneekula - that functionality is pretty cool! I wasn't aware I could show and hide frames but in this particular instance I have a different issue. I figured it would be easier to just show rather than tell so here is a little example I put together.

  1. import wx
  2. import wx.lib.ogl as ogl
  3.  
  4. class NodeNameDialog(wx.MiniFrame):
  5.  
  6. """Frame prompts user to input a name for the node."""
  7.  
  8. def __init__(self, parent, id, title, position):
  9.  
  10. """Background & text box arranged appropriately and focus set on frame."""
  11.  
  12. wx.MiniFrame.__init__(self, parent, id, title, position, size=(300, 300), style=wx.DEFAULT_FRAME_STYLE)
  13.  
  14. self.parent = parent
  15. self.SetBackgroundColour('#D3D3D3')
  16.  
  17. box = wx.BoxSizer(wx.HORIZONTAL) # a horizontal layout will be used
  18. self.textBox = wx.TextCtrl(self, -1, "child", size=(80,-1))
  19. self.textBox.Bind(wx.EVT_KEY_DOWN, self.on_name_key_down) # the text box expects key strokes
  20. self.textBox.SetFocus()
  21. box.Add(self.textBox, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
  22. self.SetSizer(box)
  23. box.Fit(self)
  24.  
  25. def on_name_key_down(self, event):
  26. """Define what to do when certain keystrokes are used on name dialog."""
  27. keycode = event.GetKeyCode()
  28. if keycode == wx.WXK_RETURN: # set node name to be the text user entered
  29. self.set_shape_text(self.textBox.GetValue())
  30. self.parent.Refresh(False)
  31. self.Destroy()
  32. # TODO: check this???? focus should be set to canvas here???
  33. if keycode == wx.WXK_ESCAPE: # do nothing if user pressed Escape
  34. self.Destroy()
  35. event.Skip()
  36.  
  37. def set_shape_text(self, text):
  38. """Set the name of the node only if the text user entered is not empty."""
  39. if not (text == ""):
  40. region = self.parent.currentShape.GetRegions()[0]
  41. region.SetText(text)
  42. self.parent.reformat_regions(self.parent.currentShape)
  43. self.Refresh(False)
  44.  
  45.  
  46. class MyEvtHandler(ogl.ShapeEvtHandler):
  47. """
  48. Overwrite the default event handler to implement some custom features.
  49. """
  50. def __init__(self):
  51. ogl.ShapeEvtHandler.__init__(self)
  52.  
  53.  
  54. def OnLeftDoubleClick(self, x, y, keys=0, attachment=0):
  55. toShape = self.GetShape()
  56. toShape.GetCanvas().currentShape = toShape
  57. posnFrame = (toShape.GetX()+200, toShape.GetY())
  58. nameNode = NodeNameDialog(toShape.GetCanvas(), -1, 'Node name:', posnFrame)
  59. nameNode.Show(True)
  60.  
  61. def OnLeftClick(self, x, y, keys=0, attachment=0):
  62. shape = self.GetShape()
  63. canvas = shape.GetCanvas()
  64. dc = wx.ClientDC(canvas)
  65. canvas.PrepareDC(dc)
  66. if shape.Selected():
  67. shape.Select(False, dc)
  68. #canvas.Redraw(dc)
  69. canvas.Refresh(False)
  70. else:
  71. redraw = False
  72. shapeList = canvas.GetDiagram().GetShapeList()
  73. toUnselect = []
  74. for s in shapeList:
  75. if s.Selected():
  76. toUnselect.append(s)
  77. shape.Select(True, dc)
  78. if toUnselect:
  79. for s in toUnselect:
  80. s.Select(False, dc)
  81. canvas.Refresh(False)
  82.  
  83.  
  84. class OGLCanvas(ogl.ShapeCanvas):
  85. def __init__(self, parent, frame):
  86. ogl.ShapeCanvas.__init__(self, parent)
  87.  
  88. maxWidth = 100
  89. maxHeight = 100
  90. self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20)
  91.  
  92. self.SetBackgroundColour("LIGHT BLUE")
  93. self.diagram = ogl.Diagram()
  94. self.SetDiagram(self.diagram)
  95. self.diagram.SetCanvas(self)
  96. self.currentShape = None
  97. self.shapes = []
  98. self.save_gdi = []
  99.  
  100. one = self.MyAddShape(
  101. ogl.CircleShape(80),
  102. 75, 110, wx.Pen(wx.BLUE, 3), wx.GREEN_BRUSH, "Root")
  103. two = self.MyAddShape(
  104. ogl.TextShape(120, 45),
  105. 160, 35, wx.GREEN_PEN, wx.LIGHT_GREY_BRUSH, "node 1")
  106. self.MyAddShape(
  107. ogl.TextShape(120, 45),
  108. 270, 35, wx.GREEN_PEN, wx.LIGHT_GREY_BRUSH, "node 2")
  109.  
  110. self.shapes.append(one)
  111. self.shapes.append(two)
  112.  
  113. self.MyAddLink()
  114.  
  115. self.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
  116.  
  117. def on_key_down(self, event):
  118. """Define what to do when certain keystrokes are used."""
  119. keycode = event.GetKeyCode()
  120.  
  121. if keycode == wx.WXK_DELETE: # delete shape selected
  122. print "delete"
  123. if keycode == wx.WXK_INSERT: # create a child node for shape selected
  124. print "insert"
  125. event.Skip()
  126.  
  127. def MyAddLink(self):
  128. for x in range(len(self.shapes)):
  129. fromShape = self.shapes[x]
  130. if x+1 == len(self.shapes):
  131. toShape = self.shapes[0]
  132. else:
  133. toShape = self.shapes[x+1]
  134.  
  135. line = ogl.LineShape()
  136. line.SetCanvas(self)
  137. line.SetPen(wx.BLACK_PEN)
  138. line.SetBrush(wx.BLACK_BRUSH)
  139. line.AddArrow(ogl.ARROW_ARROW)
  140. line.MakeLineControlPoints(2)
  141. fromShape.AddLine(line, toShape)
  142. self.diagram.AddShape(line)
  143. line.Show(True)
  144.  
  145. def MyAddShape(self, shape, x, y, pen, brush, text):
  146. # Composites have to be moved for all children to get in place
  147. if isinstance(shape, ogl.CompositeShape):
  148. dc = wx.ClientDC(self)
  149. self.PrepareDC(dc)
  150. shape.Move(dc, x, y)
  151. else:
  152. shape.SetDraggable(True, True)
  153. shape.SetCanvas(self)
  154. shape.SetX(x)
  155. shape.SetY(y)
  156. if pen: shape.SetPen(pen)
  157. if brush: shape.SetBrush(brush)
  158. if text:
  159. for line in text.split('\n'):
  160. shape.AddText(line)
  161. #shape.SetShadowMode(ogl.SHADOW_RIGHT)
  162. self.diagram.AddShape(shape)
  163. shape.Show(True)
  164.  
  165. evthandler = MyEvtHandler()
  166. evthandler.SetShape(shape)
  167. evthandler.SetPreviousHandler(shape.GetEventHandler())
  168. shape.SetEventHandler(evthandler)
  169.  
  170. return shape
  171.  
  172. def reformat_regions(self, shape):
  173. """Ensures the text displays correctly for a shape region."""
  174. rnum = 0
  175. canvas = shape.GetCanvas()
  176. dc = wx.ClientDC(canvas) # used for measuring
  177. for region in shape.GetRegions():
  178. text = region.GetText()
  179. region.SetFormatMode(ogl.FORMAT_SIZE_TO_CONTENTS)
  180. shape.FormatText(dc, text, rnum)
  181. rnum += 1
  182.  
  183.  
  184. class OGLFrame(wx.Frame):
  185. def __init__(self, *args, **kwds):
  186. wx.Frame.__init__(self, *args, **kwds)
  187.  
  188. self.SetTitle("Testing right click")
  189. self.SetBackgroundColour(wx.Colour(8, 197, 248))
  190. self.canvas = OGLCanvas(self, self)
  191.  
  192. if __name__ == "__main__":
  193. app = wx.PySimpleApp(False)
  194. wx.InitAllImageHandlers()
  195. ogl.OGLInitialize()
  196. frame = OGLFrame(None, -1, "")
  197. app.SetTopWindow(frame)
  198. frame.Show(True)
  199. app.MainLoop()

In the code above when we start up the app pressing insert and delete means that we will see stuff print out as expected. Then after we double click on a shape and the frame shows up and we write something in it then press enter the frame is destroyed. Now I want to know what can I do that without a mouse click the focus can be set back to the canvas so that pressing insert and delete will once again print stuff...where can I put the SetFocus() method so this works?

Thanks
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC