wxpython set Focus to wx.Menubar by pressing a key - python

I have a wx.menubar in my application, and I want to set focus to it by pressing a key, for example, "alt+o", and have as a result this:
I would like to know if it is possible? or if an event in wxpython to do it exists. Thank you. P.D: I have tried to use the SetFocus () method which extends from wx.Window but it doesn't work

You could use accelerators
For example:
# ...
# Menu Bar
self.menubar = wx.MenuBar()
file_menu = wx.Menu()
item = file_menu.Append(wx.ID_EXIT, "&Salir", "")
self.menubar.Append(file_menu, "Archiv&o")
self.SetMenuBar(self.menubar)
#...
You should be able to select the "Archivo" menu using "Alt + o".

Related

Adding a function directly to "menuBar" buttons without creating a sub-menu or dropdown

I want to make menu in Python PyQt5 with a function directly linked to it and not with a the sub-menu or dropdown it creates. Here is a snippet from my code:
def create_menu(self):
self.menu = self.menuBar()
self.this = self.menu.addMenu('This')
self.that = self.menu.addMenu('That')
self.menu.show()
self.this.addAction("I want to make it without this", self.there)

Can I get clickable menu item with submenu in wxPython?

I'm building system tray application with wxPython. It's easy to understand and works great so far, but I'm trying to get a non-standard behavior. I would like menu item to be clickable, but have a submenu at the same time. I know it's weird, but it would meet my needs the best. I want to execute default action on click, but have more options in submenu. The below code creates items just fine without submenu.
class TrackerMenuItem(wx.MenuItem):
#staticmethod
def create_and_bind(parent_menu, label, handler):
menu_item = TrackerMenuItem(parent_menu, -1, label)
parent_menu.Bind(wx.EVT_MENU, handler, id=menu_item.GetId())
parent_menu.Append(menu_item)
return menu_item
But if I try to add submenu, binding stops working, and my item is just a parent for submenu (this is just a generic code for tests)
class TrackerMenuItem(wx.MenuItem):
#staticmethod
def create_and_bind(parent_menu, label, handler):
menu_item = TrackerMenuItem(parent_menu, -1, label)
submenu = wx.Menu()
submenuitem = wx.MenuItem(submenu, wx.ID_ANY, 'Submenu Item')
submenu.Append(submenuitem)
menu_item.SetSubMenu(submenu)
parent_menu.Bind(wx.EVT_MENU, handler, id=menu_item.GetId())
parent_menu.Append(menu_item)
return menu_item
Is it possible to work it around in a reasonable manner?

How do I programmatically pull down a wx.Menu in wxPython

If I have a wx.Menu (in a wx.MenuBar, at the top of a frame, like normal) - how can I cause that menu to drop down and take focus, without clicking on it. I want the behavior to be as if the user had pressed the keyboard accelerator shortcut for that menu (so Alt+F for example, for the &File menu)
Try with wx.PostEvent:
event = wx.MenuEvent(wx.wxEVT_LEFT_DOWN, menuitem.GetId(), menu)
wx.PostEvent(frame, event)
Other wx mouse events: http://www.wxpython.org/docs/api/wx.MouseEvent-class.html
Found in google groups thread
I had the same requirement and found the simple way of using the PopupMenu function. It is not called from the menu object but from the parent of the menu (the window, frame, etc..)
To make sure that the menu appears at a specific position, regardless of your mouse, supply to the PopupMenu function a position parameter as well.
In the example bellow, I turned a platebtn that was opening the menu only when clicked in the right side, in the small area of the down arrow, into a button that opens the same menu in the same way when you click it anywhere on its surface.
Example:
import wx
import wx.lib.platebtn as platebtn
class MyFrame(wx.Frame):
def __init__(self, parent, ID, title):
wx.Frame.__init__(self, parent, ID, title, size=(300, 250))
wx.Panel(self,-1, style=wx.SUNKEN_BORDER)
droparrow = platebtn.PB_STYLE_DROPARROW | platebtn.PB_STYLE_SQUARE | platebtn.PB_STYLE_GRADIENT
self.btn1 = platebtn.PlateButton(self, wx.ID_ANY, label=" File ", style=droparrow)
self.btn1.SetPressColor(wx.LIGHT_GREY)
self.menu1 = wx.Menu()
self.menu1.Append(1, "New")
self.menu1.Append(2, "Open")
self.menu1.Append(3, "Exit")
sm = wx.Menu()
sm.Append(8, "sub item 1")
sm.Append(9, "sub item 1")
self.menu1.AppendMenu(7, "Test Submenu", sm)
self.btn1.SetMenu(self.menu1)
self.Bind(wx.EVT_BUTTON, self.OnFile, self.btn1)
def OnFile(self, event):
self.btn1.PopupMenu(self.menu1, pos=(1, self.btn1.GetSize()[1]))
app = wx.App(False)
frame = MyFrame(None, -1, "PopupMenu example")
frame.Show()
app.MainLoop()
To define accelerators for menu in your program,Understand through the given example
example:
file_menu=wx.Menu()
menubar=wx.MenuBar()
menubar.Append(file_menu,"&File")
self.SetMenuBar(menubar)
Now we can access the File menu (here) by pressing ALT+F.
If we have other menus too,on pressing ALT ,it will point to the first Letter of menu bar,from which you can press the next key according to the name of menu_item.

wxPython menu text alignment

I'm developing a wxPython GUI, and would like to right-align shortcut text. Obviously one can cludge this using tab characters, but I'd prefer to do it natively if there is a way to.
The default menu item creation is thus:
menu = wx.Menu()
item_id = 1
item_name = 'My menu item'
help_text = 'Clicking this does something interesting.'
item = menu.Append(item_id, item_name, help_text)
I'll be expanding on this with shortcuts, so if I were using tabs, it would be something like:
item_name = 'My menu item\t\tCtrl+Alt+H'
However, that involves a lot of manual \t entries to make sure everything lines up, and anytime a menu item changes name or another item is added, they would all potentially need to be updated. Is there any way around this, e.g. a class method I'm not seeing to automatically associate the keybinding to the menu item?
Edit: I know that when passing text like &My menu item, it does something automatically with the keybinding associated with the ID specified if there is a definition associated with that ID in the accelerators table, correct?
I went digging through a couple other application's code to find the answer. It turns out the default behavior with \t doesn't do what it looks like it would do (i.e. insert a tab character), but is sensibly interpreted by the toolkit as doing precisely what I wanted to do. Thus, the way to right-align a short cut is simple: create it with the text you desire, followed by \t<shortcut> (rather as I had above). In the example code I pasted above, if I wanted my shortcut to be Ctrl + T, it should therefore be thus:
menu = wx.Menu()
item_id = 1
item_name = 'My menu item\tCtrl+T'
help_text = 'Clicking this does something interesting.'
item = menu.Append(item_id, item_name, help_text)
Edit: updated the following section based on Mike Driscoll's very helpful answer.
Note that this creates the shortcut binding (wxPython picks that up), but it doesn't make it selectable using e.g. the Alt key on Windows.
You can associate the Alt key to quickly open the menu and navigate to it by using the ampersand in your item_name text, but you'll still need to associate the desired keybinding manually via the AcceleratorTable:
menu = wx.Menu()
item_id = 1
# Ctrl+T is bound to the keybinding
accelerator_table = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('T'), item_id)])
self.setAcceleratorTable(accelerator_table)
# Ctrl+T is not included, but the menu item can be accessed via Alt key
item_name = '&My menu item'
help_text = 'Clicking this does something interesting.'
item = menu.Append(item_id, item_name, help_text)
This, I imagine, would actually be the preferred pattern, as then anywhere that the item_id was referenced, the shortcut could be referenced automatically. This would also make for seamless updates.
While Chris is right about "\t" indenting the keybinding correctly in the menu, I don't really see what he means by automatically associating anything using an ampersand. The ampersand (&) DOES allow the used to type ALT to get the File menu to open and then if you type another letter that has had the ampersand applied to it, it will jump to that menu item, but the & does not connect the menu item to the accelerator table. That is done via the menu item's ID.
See the following code:
import wx
########################################################################
class MyForm(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "wx.Menu Tutorial")
self.panel = wx.Panel(self, wx.ID_ANY)
menuBar = wx.MenuBar()
fileMenu = wx.Menu()
exitId = wx.NewId()
exitMenuItem = fileMenu.Append(exitId, "&Exit/tCtrl+X",
"Exit the application")
self.Bind(wx.EVT_MENU, self.onExit, id=exitId )
menuBar.Append(fileMenu, "&File")
self.SetMenuBar(menuBar)
accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('X'), exitId )])
self.SetAcceleratorTable(accel_tbl)
#----------------------------------------------------------------------
def onExit(self, event):
""""""
self.Close()
# Run the program
if __name__ == "__main__":
app = wx.App(False)
frame = MyForm().Show()
app.MainLoop()
Note that the exitId is used to create the menu item, bind the menu item to EVT_MENU and finally, it is used in the AcceleratorTable so the user can use the shortcut key.
Here are a few references that might be helpful:
http://www.blog.pythonlibrary.org/2008/07/02/wxpython-working-with-menus-toolbars-and-accelerators/
http://wiki.wxpython.org/WorkingWithMenus
http://zetcode.com/wxpython/menustoolbars/
http://www.blog.pythonlibrary.org/2010/12/02/wxpython-keyboard-shortcuts-accelerators/

How to add keyboard navigation to a menu?

How can I add keyboard navigation (using Alt with underlines to suggest what other keys to use) to a python gtk gobject-introspection application.
This code works for showing a simple menu but does not add keyboard navigation:
mb = Gtk.MenuBar()
filemenu = Gtk.Menu()
filem = Gtk.MenuItem()
filem.set_label("File")
filem.set_submenu(filemenu)
closem = Gtk.MenuItem()
closem.show()
closem.set_label("Close")
closem.connect("activate", Gtk.main_quit)
filemenu.append(closem)
mb.append(filem)
How can I change it to allow keyboard navigation?
Set the use-underline property and prepend _ to the key you want to use as shortcut.
close_menu = Gtk.MenuItem()
close_menu.set_label("_Close")
close_menu.set_use_underline(True)
If your version of PyGObject is recent enough, you can also use
close_menu = Gtk.MenuItem("_Close", True)

Categories

Resources