Ross Wan's World!

Python, Ajax, PHP and Linux.

wxPython:菜单和工具栏

Posted by Ross Wan 于 2008/03/09

创建菜单栏
   
       用 wxPython 创建一个菜单栏,需要用到 wx.MenuBar,wxMenu  和 wx.MenuItem。

一个简单的菜单示例

#!/usr/bin/python
# simplemenu.py

import wx

class SimpleMenu(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 150))

        menubar = wx.MenuBar()       # 创建一个菜单栏对象
        file = wx.Menu()             # 创建一个菜单对象
        file.Append(-1, ‘Quit’, ‘Quit application’)       # 将菜单添加到菜单栏上
        menubar.Append(file, ‘&File’)
        self.SetMenuBar(menubar)

        self.Centre()
        self.Show(True)

app = wx.App()
SimpleMenu(None, -1, ‘simple menu example’)
app.MainLoop()

       file.Append(-1, ‘Quit’, ‘Quit application’),第一个参数是菜单项的 ID,第二个参数是菜单项的名称,第三个参数是当菜单项被选中时显示在状态栏的文字信息。注意,我们这里没有使用 wx.MenuItem 直接创建菜单项。

menubar.Append(file, ‘&File’)
self.SetMenuBar(menubar)

       上面的代码将菜单添加到菜单栏上。字符“&”用来设置菜单的加速键,这样,就可以通过 alt + F 来打开 File 菜单。最后,通过调用 wx.Frame 的setMenu() 设置窗口的菜单栏。

创建 dockable 菜单栏

#!/usr/bin/python
# dockable.py

import wx

class Dockable(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)

        menubar = wx.MenuBar(wx.MB_DOCKABLE)
        file = wx.Menu()
        edit = wx.Menu()
        view = wx.Menu()
        insr = wx.Menu()
        form = wx.Menu()
        tool = wx.Menu()
        help = wx.Menu()

        menubar.Append(file, ‘&File’)
        menubar.Append(edit, ‘&Edit’)
        menubar.Append(view, ‘&View’)
        menubar.Append(insr, ‘&Insert’)
        menubar.Append(form, ‘&Format’)
        menubar.Append(tool, ‘&Tools’)
        menubar.Append(help, ‘&Help’)
        self.SetMenuBar(menubar)

        self.Centre()
        self.Show(True)

app = wx.App()
Dockable(None, -1, ‘Dockable menubar’)
app.MainLoop()

       仅需在 wx.MenuBar(wx.MB_DOCKABLE) 构造函数是提供一个 wx.MB_DOCKABLE 参数即可。

图标,快捷键,事件

       下面,我们将进一步增加上面的菜单示例,为菜单添加图标、快捷键、事件处理。

#!/usr/bin/python

# menuexample.py

import wx

class MenuExample(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 150))

        menubar = wx.MenuBar()
        file = wx.Menu()
        quit = wx.MenuItem(file, 1, ‘&Quit\tCtrl+Q’)
        quit.SetBitmap(wx.Bitmap(‘icons/exit.png’))
        file.AppendItem(quit)

        self.Bind(wx.EVT_MENU, self.OnQuit, id=1)

        menubar.Append(file, ‘&File’)
        self.SetMenuBar(menubar)

        self.Centre()
        self.Show(True)

    def OnQuit(self, event):
        self.Close()

app = wx.App()
MenuExample(None, -1, ”)
app.MainLoop()

       如果我们需要添加快捷键和图标到菜单上,必须使用 wx.MenuItem 显式创建菜单项。

quit = wx.MenuItem(file, 1, ‘&Quit\tCtrl+Q’)
quit.SetBitmap(wx.Bitmap(‘icons/exit.png’))
file.AppendItem(quit)

       “&”用来指定菜单的加速键。现实中,菜单项的快捷键通常是组合键,如上面定义的“Ctrl + Q”,只需在加速键与快捷键之间添加一个制表符“\t”即可。SetBitmap() 可以设置菜单项的图标。

self.Bind(wx.EVT_MENU, self.OnQuit, id=1)

       如果选择了 quit 菜单项或者按下相应的快捷键,wx.EVT_MENU 就会引发一个事件。我们可以用 bind() 来绑定指定事件的处理方法。在上面的例子中,绑定到 OnQuit() 方法,用来关闭应用程序。如果有多个菜单项,必须为它们定义唯一的 ID。

子菜单

       在下面的例子中,我们将创建子菜单和菜单项分隔条。

#!/usr/bin/python
# submenu.py

import wx

ID_QUIT = 1

class SubmenuExample(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(350, 250))

        menubar = wx.MenuBar()

        file = wx.Menu()
        file.Append(-1, ‘&New’)
        file.Append(-1, ‘&Open’)
        file.Append(-1, ‘&Save’)
        file.AppendSeparator()

        imp = wx.Menu()
        imp.Append(-1, ‘Import newsfeed list…’)
        imp.Append(-1, ‘Import bookmarks…’)
        imp.Append(-1, ‘Import mail…’)

        file.AppendMenu(-1, ‘I&mport’, imp)

        quit = wx.MenuItem(file, ID_QUIT, ‘&Quit\tCtrl+W’)
        quit.SetBitmap(wx.Bitmap(‘icons/exit.png’))
        file.AppendItem(quit)

        self.Bind(wx.EVT_MENU, self.OnQuit, id=ID_QUIT)

        menubar.Append(file, ‘&File’)
        self.SetMenuBar(menubar)

        self.Centre()
        self.Show(True)

    def OnQuit(self, event):
        self.Close()

app = wx.App()
SubmenuExample(None, -1, ‘Submenu’)
app.MainLoop()

       简单的调用 file.AppendSeparator() 即可添加一个分隔条。使用 AppendMenu() 就可以像将一个菜单(子菜单)添加到另一个菜单上。

菜单项的分类

       有三种菜单项:

  • normal item
  • check item
  • radio item
#!/usr/bin/python
# checkmenuitem.py

import wx

ID_STAT = 1
ID_TOOL = 2

class CheckMenuItem(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(350, 250))

        menubar = wx.MenuBar()
        file = wx.Menu()
        view = wx.Menu()
        self.shst = view.Append(ID_STAT, ‘Show statubar’, ‘Show Statusbar’, kind=wx.ITEM_CHECK)
        self.shtl = view.Append(ID_TOOL, ‘Show toolbar’, ‘Show Toolbar’, kind=wx.ITEM_CHECK)
        view.Check(ID_STAT, True)
        view.Check(ID_TOOL, True)

        self.Bind(wx.EVT_MENU, self.ToggleStatusBar, id=ID_STAT)
        self.Bind(wx.EVT_MENU, self.ToggleToolBar, id=ID_TOOL)

        menubar.Append(file, ‘&File’)
        menubar.Append(view, ‘&View’)
        self.SetMenuBar(menubar)

        self.toolbar = self.CreateToolBar()
        self.toolbar.AddLabelTool(3, ”, wx.Bitmap(‘icons/quit.png’))

        self.statusbar = self.CreateStatusBar()
        self.Centre()
        self.Show(True)

    def ToggleStatusBar(self, event):
        if self.shst.IsChecked():
            self.statusbar.Show()
        else:
            self.statusbar.Hide()

    def ToggleToolBar(self, event):
        if self.shtl.IsChecked():
            self.toolbar.Show()
        else:
            self.toolbar.Hide()

app = wx.App()
CheckMenuItem(None, -1, ‘check menu item’)
app.MainLoop()

self.shst = view.Append(ID_STAT, ‘Show statubar’, ‘Show Statusbar’, kind=wx.ITEM_CHECK)
self.shtl = view.Append(ID_TOOL, ‘Show toolbar’, ‘Show Toolbar’, kind=wx.ITEM_CHECK)

       设置 Append() 的 kind 参数为 wx.ITEM_CHECK 即可创建一个 check 菜单项,kind 的默认值为 wx.ITEM_NORMAL。Append() 方法将返回一个 wx.MenuItem 对象。

view.Check(ID_STAT, True)
view.Check(ID_TOOL, True)

       使用菜单项的 Check() 方法即可设置 check 菜单项的状态。

 def ToggleStatusBar(self, event):
     if self.shst.IsChecked():
         self.statusbar.Show()
     else:
         self.statusbar.Hide()

       我们全用 IsChecked() 方法取得 check 菜单项的状态,且以此为根据来显示或者隐藏状态栏。

上下文菜单(Context menu)

       上下文菜单有时被称为弹出菜单或者右键菜单。

# contextmenu.py

import wx

class MyPopupMenu(wx.Menu):
    def __init__(self, parent):
        wx.Menu.__init__(self)

        self.parent = parent

        minimize = wx.MenuItem(self, wx.NewId(), ‘Minimize’)
        self.AppendItem(minimize)
        self.Bind(wx.EVT_MENU, self.OnMinimize, id=minimize.GetId())

        close = wx.MenuItem(self, wx.NewId(), ‘Close’)
        self.AppendItem(close)
        self.Bind(wx.EVT_MENU, self.OnClose, id=close.GetId())

    def OnMinimize(self, event):
        self.parent.Iconize()

    def OnClose(self, event):
        self.parent.Close()

class ContextMenu(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 150))

        self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)

        self.Center()
        self.Show()

    def OnRightDown(self, event):
        self.PopupMenu(MyPopupMenu(self), event.GetPosition())

app = wx.App()
frame = ContextMenu(None, -1, ‘context menu’)
app.MainLoop()

 class MyPopupMenu(wx.Menu):
     def __init__(self, parent):
         wx.Menu.__init__(self)

       上面创建另外一个 wx.Menu 菜单对象,并定义了两个命令: 关闭和最小化窗口。

self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)

       我们将按下右键的事件绑定到 OnRightDown() 方法。

 def OnRightDown(self, event):
     self.PopupMenu(MyPopupMenu(self), event.GetPosition())

       在 OnRightDown() 方法中,调用 PopuMenu() 方法显示上下文菜单,第一个参数用来指定显示的菜单对象,第二个参数指定上下文菜单显示的位置,这里指定是鼠标的位置 —— 使用 GetPosition() 即可取得当前鼠标的位置。

工具栏

       工具栏提供了一个快速的执行常用命令的通道。

CreateToolBar(long style=-1, int winid=-1, String name=ToolBarNameStr)

       通过调 frame 的 CreateToolBar() 方法即可创建一个工具栏。

#!/usr/bin/python
# simpletoolbar.py

import wx

class SimpleToolbar(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(300, 200))

        toolbar = self.CreateToolBar()
        toolbar.AddLabelTool(wx.ID_EXIT, ”, wx.Bitmap(‘../icons/exit.png’))
    toolbar.Realize()

        self.Bind(wx.EVT_TOOL, self.OnExit, id=wx.ID_EXIT)

        self.Centre()
        self.Show(True)

    def OnExit(self, event):
        self.Close()

app = wx.App()
SimpleToolbar(None, -1, ‘simple toolbar’)
app.MainLoop()

toolbar.AddLabelTool(wx.ID_EXIT, ”, wx.Bitmap(‘../icons/exit.png’))

       使用 AddLabelTool() 方法创建一个工具栏按钮。

toolbar.Realize()

       对于 Windows 系统,当添加按钮后,我们必须调用 Realize() 方法。在 Linux 下则不必。

self.Bind(wx.EVT_TOOL, self.OnExit, id=wx.ID_EXIT)

       绑定工具栏的事件。

       对于创建多个工具栏,必须按照跟上面不同的方式:

#!/usr/bin/python
# toolbars.py

import wx

class Toolbars(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(300, 200))

        vbox = wx.BoxSizer(wx.VERTICAL)

        toolbar1 = wx.ToolBar(self, -1)
        toolbar1.AddLabelTool(wx.ID_ANY, ”, wx.Bitmap(‘../icons/new.png’))
        toolbar1.AddLabelTool(wx.ID_ANY, ”, wx.Bitmap(‘../icons/open.png’))
        toolbar1.AddLabelTool(wx.ID_ANY, ”, wx.Bitmap(‘../icons/save.png’))
        toolbar1.Realize()

        toolbar2 = wx.ToolBar(self, -1)
        toolbar2.AddLabelTool(wx.ID_EXIT, ”, wx.Bitmap(‘../icons/exit.png’))
        toolbar2.Realize()

        vbox.Add(toolbar1, 0, wx.EXPAND)
        vbox.Add(toolbar2, 0, wx.EXPAND)

        self.Bind(wx.EVT_TOOL, self.OnExit, id=wx.ID_EXIT)

        self.SetSizer(vbox)
        self.Centre()
        self.Show(True)

    def OnExit(self, event):
        self.Close()

app = wx.App()
Toolbars(None, -1, ‘toolbars’)
app.MainLoop()

 toolbar1 = wx.ToolBar(self, -1)
 …
 toolbar2 = wx.ToolBar(self, -1)

       将两个工具栏放于一个 vertical box 中。

       有时,我们需要创建一垂直放置的工具栏:

#!/usr/bin/python
# verticaltoolbar.py

import wx

class VerticalToolbar(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(240, 300))

        toolbar = self.CreateToolBar(wx.TB_VERTICAL)
        toolbar.AddLabelTool(wx.ID_ANY, ”, wx.Bitmap(‘../icons/select.gif’))
        toolbar.AddLabelTool(wx.ID_ANY, ”, wx.Bitmap(‘../icons/freehand.gif’))
        toolbar.AddLabelTool(wx.ID_ANY, ”, wx.Bitmap(‘../icons/shapeed.gif’))
        toolbar.AddLabelTool(wx.ID_ANY, ”, wx.Bitmap(‘../icons/pen.gif’))
        toolbar.AddLabelTool(wx.ID_ANY, ”, wx.Bitmap(‘../icons/rectangle.gif’))
        toolbar.AddLabelTool(wx.ID_ANY, ”, wx.Bitmap(‘../icons/ellipse.gif’))
        toolbar.AddLabelTool(wx.ID_ANY, ”, wx.Bitmap(‘../icons/qs.gif’))
        toolbar.AddLabelTool(wx.ID_ANY, ”, wx.Bitmap(‘../icons/text.gif’))

        toolbar.Realize()

        self.Centre()
        self.Show(True)

    def OnExit(self, event):
        self.Close()

app = wx.App()
VerticalToolbar(None, -1, ‘vertical toolbar’)
app.MainLoop()

toolbar = self.CreateToolBar(wx.TB_VERTICAL)

       提供一个 wx.TB_VERTICAL 参数即可创建一个垂直放置的工具栏。

       在下面的例子中,我们将演示 Enable/Disable 工具栏按钮,以及添加分隔条:

#!/usr/bin/python
# enabledisable.py

import wx

class EnableDisable(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 150))

        self.count = 5

        self.toolbar = self.CreateToolBar()
        self.toolbar.AddLabelTool(wx.ID_UNDO, ”, wx.Bitmap(‘../icons/undo.png’))
        self.toolbar.AddLabelTool(wx.ID_REDO, ”, wx.Bitmap(‘../icons/redo.png’))
        self.toolbar.EnableTool(wx.ID_REDO, False)
        self.toolbar.AddSeparator()
        self.toolbar.AddLabelTool(wx.ID_EXIT, ”, wx.Bitmap(‘../icons/exit.png’))
        self.toolbar.Realize()

        self.Bind(wx.EVT_TOOL, self.OnExit, id=wx.ID_EXIT)
        self.Bind(wx.EVT_TOOL, self.OnUndo, id=wx.ID_UNDO)
        self.Bind(wx.EVT_TOOL, self.OnRedo, id=wx.ID_REDO)

        self.Centre()
        self.Show(True)

    def OnUndo(self, event):
        if self.count > 1 and self.count <= 5:
            self.count = self.count – 1

        if self.count == 1:
            self.toolbar.EnableTool(wx.ID_UNDO, False)

        if self.count == 4:
            self.toolbar.EnableTool(wx.ID_REDO, True)

    def OnRedo(self, event):
        if self.count < 5 and self.count >= 1:
            self.count = self.count + 1

        if self.count == 5:
            self.toolbar.EnableTool(wx.ID_REDO, False)

        if self.count == 2:
            self.toolbar.EnableTool(wx.ID_UNDO, True)

    def OnExit(self, event):
        self.Close()

app = wx.App()
EnableDisable(None, -1, ‘enable disable’)
app.MainLoop()

       在例子中,我们创建了三个工具栏按钮 —— 退出、撤销、重做按钮。而 撤销、重做按钮是 Disable 的。

 self.toolbar.EnableTool(wx.ID_REDO, False)
 self.toolbar.AddSeparator()

       调用 EnableTool() 方法使重做按钮 Disable。简单调用 AddSparator() 即可添加分隔条。

 def OnUndo(self, event):
     if self.count > 1 and self.count <= 5:
         self.count = self.count – 1

     if self.count == 1:
         self.toolbar.EnableTool(wx.ID_UNDO, False)

     if self.count == 4:
         self.toolbar.EnableTool(wx.ID_REDO, True)

       我们模拟了撤销和重做的功能,最多可以返回4次的改变。如果没有可以撤销的,撤销按钮将会被设置为 Disable。当第一次按下撤销按钮之后,重做按钮被设置为 Enable。上面的逻辑同样适合于 OnRedo() 方法。

Advertisements

一条回应 to “wxPython:菜单和工具栏”

  1. Ross Wan said

    翻译自:The wxPython tutorial

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

 
%d 博主赞过: