| | |
SetFocus() on canvas not working?
Please support our Python advertiser: Programming Forums - DaniWeb Sister Site
![]() |
•
•
Join Date: Aug 2008
Posts: 29
Reputation:
Solved Threads: 0
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...
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...
You can use Hide() and Show() as explained here:
python Syntax (Toggle Plain Text)
# create two frames with wxFrame, only one is showing import wx class Frame1(wx.Frame): def __init__(self, parent, mytitle): wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle) self.SetBackgroundColour("green") # pass frame1 to frame2 as instance self self.frame2 = Frame2(None, 'Frame1', self) # create input widgets self.button1 = wx.Button(self, wx.ID_ANY, label='Frame2') self.button2 = wx.Button(self, wx.ID_ANY, label='Button2') self.button3 = wx.Button(self, wx.ID_ANY, label='Button3') # bind mouse event to an action self.button1.Bind(wx.EVT_BUTTON, self.button1Click) # use a box sizer to lay out widgets sizer_v = wx.BoxSizer(wx.VERTICAL) # Add(widget, proportion, flag, border) sizer_v.Add(self.button1, 0, flag=wx.ALL, border=10) sizer_v.Add(self.button2, 0, flag=wx.ALL, border=10) sizer_v.Add(self.button3, 0, flag=wx.ALL, border=10) self.SetSizer(sizer_v) # size the frame so all the widgets fit self.Fit() def button1Click(self, event): """button1 has been left clicked""" # self is instance frame1 self.Hide() self.frame2.Show() class Frame2(wx.Frame): def __init__(self, parent, mytitle, frame1): wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle) self.SetBackgroundColour("brown") self.frame1 = frame1 # create input widgets self.button1 = wx.Button(self, wx.ID_ANY, label='Frame1') self.button2 = wx.Button(self, wx.ID_ANY, label='Button2') self.button3 = wx.Button(self, wx.ID_ANY, label='Button3') # bind mouse event to an action self.button1.Bind(wx.EVT_BUTTON, self.button1Click) # responds to exit symbol x on frame2 title bar self.Bind(wx.EVT_CLOSE, self.button1Click) # use a box sizer to lay out widgets sizer_v = wx.BoxSizer(wx.VERTICAL) # Add(widget, proportion, flag, border) sizer_v.Add(self.button1, 0, flag=wx.ALL, border=10) sizer_v.Add(self.button2, 0, flag=wx.ALL, border=10) sizer_v.Add(self.button3, 0, flag=wx.ALL, border=10) self.SetSizer(sizer_v) # size the frame so all the widgets fit self.Fit() def button1Click(self, event): """button1 has been left clicked""" # self is instance frame2 self.Hide() self.frame1.Show() app = wx.App(0) # create a MyFrame instance and show the frame frame1 = Frame1(None, 'Frame1') frame1.Show() app.MainLoop()
No one died when Clinton lied.
•
•
Join Date: Aug 2008
Posts: 29
Reputation:
Solved Threads: 0
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.
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
Python Syntax (Toggle Plain Text)
import wx import wx.lib.ogl as ogl class NodeNameDialog(wx.MiniFrame): """Frame prompts user to input a name for the node.""" def __init__(self, parent, id, title, position): """Background & text box arranged appropriately and focus set on frame.""" wx.MiniFrame.__init__(self, parent, id, title, position, size=(300, 300), style=wx.DEFAULT_FRAME_STYLE) self.parent = parent self.SetBackgroundColour('#D3D3D3') box = wx.BoxSizer(wx.HORIZONTAL) # a horizontal layout will be used self.textBox = wx.TextCtrl(self, -1, "child", size=(80,-1)) self.textBox.Bind(wx.EVT_KEY_DOWN, self.on_name_key_down) # the text box expects key strokes self.textBox.SetFocus() box.Add(self.textBox, 1, wx.ALIGN_CENTRE|wx.ALL, 5) self.SetSizer(box) box.Fit(self) def on_name_key_down(self, event): """Define what to do when certain keystrokes are used on name dialog.""" keycode = event.GetKeyCode() if keycode == wx.WXK_RETURN: # set node name to be the text user entered self.set_shape_text(self.textBox.GetValue()) self.parent.Refresh(False) self.Destroy() # TODO: check this???? focus should be set to canvas here??? if keycode == wx.WXK_ESCAPE: # do nothing if user pressed Escape self.Destroy() event.Skip() def set_shape_text(self, text): """Set the name of the node only if the text user entered is not empty.""" if not (text == ""): region = self.parent.currentShape.GetRegions()[0] region.SetText(text) self.parent.reformat_regions(self.parent.currentShape) self.Refresh(False) class MyEvtHandler(ogl.ShapeEvtHandler): """ Overwrite the default event handler to implement some custom features. """ def __init__(self): ogl.ShapeEvtHandler.__init__(self) def OnLeftDoubleClick(self, x, y, keys=0, attachment=0): toShape = self.GetShape() toShape.GetCanvas().currentShape = toShape posnFrame = (toShape.GetX()+200, toShape.GetY()) nameNode = NodeNameDialog(toShape.GetCanvas(), -1, 'Node name:', posnFrame) nameNode.Show(True) def OnLeftClick(self, x, y, keys=0, attachment=0): shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape.Selected(): shape.Select(False, dc) #canvas.Redraw(dc) canvas.Refresh(False) else: redraw = False shapeList = canvas.GetDiagram().GetShapeList() toUnselect = [] for s in shapeList: if s.Selected(): toUnselect.append(s) shape.Select(True, dc) if toUnselect: for s in toUnselect: s.Select(False, dc) canvas.Refresh(False) class OGLCanvas(ogl.ShapeCanvas): def __init__(self, parent, frame): ogl.ShapeCanvas.__init__(self, parent) maxWidth = 100 maxHeight = 100 self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.SetBackgroundColour("LIGHT BLUE") self.diagram = ogl.Diagram() self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.currentShape = None self.shapes = [] self.save_gdi = [] one = self.MyAddShape( ogl.CircleShape(80), 75, 110, wx.Pen(wx.BLUE, 3), wx.GREEN_BRUSH, "Root") two = self.MyAddShape( ogl.TextShape(120, 45), 160, 35, wx.GREEN_PEN, wx.LIGHT_GREY_BRUSH, "node 1") self.MyAddShape( ogl.TextShape(120, 45), 270, 35, wx.GREEN_PEN, wx.LIGHT_GREY_BRUSH, "node 2") self.shapes.append(one) self.shapes.append(two) self.MyAddLink() self.Bind(wx.EVT_KEY_DOWN, self.on_key_down) def on_key_down(self, event): """Define what to do when certain keystrokes are used.""" keycode = event.GetKeyCode() if keycode == wx.WXK_DELETE: # delete shape selected print "delete" if keycode == wx.WXK_INSERT: # create a child node for shape selected print "insert" event.Skip() def MyAddLink(self): for x in range(len(self.shapes)): fromShape = self.shapes[x] if x+1 == len(self.shapes): toShape = self.shapes[0] else: toShape = self.shapes[x+1] line = ogl.LineShape() line.SetCanvas(self) line.SetPen(wx.BLACK_PEN) line.SetBrush(wx.BLACK_BRUSH) line.AddArrow(ogl.ARROW_ARROW) line.MakeLineControlPoints(2) fromShape.AddLine(line, toShape) self.diagram.AddShape(line) line.Show(True) def MyAddShape(self, shape, x, y, pen, brush, text): # Composites have to be moved for all children to get in place if isinstance(shape, ogl.CompositeShape): dc = wx.ClientDC(self) self.PrepareDC(dc) shape.Move(dc, x, y) else: shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: for line in text.split('\n'): shape.AddText(line) #shape.SetShadowMode(ogl.SHADOW_RIGHT) self.diagram.AddShape(shape) shape.Show(True) evthandler = MyEvtHandler() evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def reformat_regions(self, shape): """Ensures the text displays correctly for a shape region.""" rnum = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) # used for measuring for region in shape.GetRegions(): text = region.GetText() region.SetFormatMode(ogl.FORMAT_SIZE_TO_CONTENTS) shape.FormatText(dc, text, rnum) rnum += 1 class OGLFrame(wx.Frame): def __init__(self, *args, **kwds): wx.Frame.__init__(self, *args, **kwds) self.SetTitle("Testing right click") self.SetBackgroundColour(wx.Colour(8, 197, 248)) self.canvas = OGLCanvas(self, self) if __name__ == "__main__": app = wx.PySimpleApp(False) wx.InitAllImageHandlers() ogl.OGLInitialize() frame = OGLFrame(None, -1, "") app.SetTopWindow(frame) frame.Show(True) 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
![]() |
Similar Threads
- CANVAS: How I can change canvas stroke on a typeface hover? stroke() doesn’t work (JavaScript / DHTML / AJAX)
- Canvas randomly erasing previously drawn images (Java)
- Refreshing a Tkinter Canvas Multiple Times: (Python)
- Canvas and Layered Images (Python)
- Working on new design (DaniWeb Community Feedback)
Other Threads in the Python Forum
- Previous Thread: How to get WSDL from web services created using SOAPpy
- Next Thread: please help
| Thread Tools | Search this Thread |
alarm assignment avogadro beginner bluetooth character cmd code customdialog cx-freeze data decimals dictionary directory dynamic error examples exe file float format function generator getvalue gnu graphics gui halp homework http ideas import input ip itunes java leftmouse line linux list lists logging loop maintain maze millimeter module mouse number numbers output parsing path port prime programming projects push py2exe pygame pyglet pyqt python queue random recursion schedule screensaverloopinactive script scrolledtext slicenotation sqlite ssh stdout string strings sudokusolver table terminal text thread threading time tlapse tuple tutorial ubuntu unicode urllib urllib2 variable variables ventrilo verify vigenere web webservice wikipedia wxpython xlib






