wxpython中文教程之弹出菜单

发布时间:2020-06-07编辑:脚本学堂
有关wxpython中弹出菜单的实现代码,在wxpython编程中怎么编写弹出菜单效果,一个例子,wxpython中文教程学习,需要的朋友参考下。

python中使用实现wxpython弹出菜单PopupMenu效果

专题:wxpython中文教程

以上代码是由Chris Barker在wxPython用户组邮件清单上提交的。

弹出菜单籍由一个独立的类实现. 采用这种方法,不必去手动检查事件是否已经绑定好了。

例子:
 

复制代码 代码示例:

#!/usr/bin/python
#coding=utf-8

#popup.py

import wx

app = wx.PySimpleApp()

class MyPopupMenu(wx.Menu):
    def __init__(self, WinName):
 wx.Menu.__init__(self)
 
 self.WinName = WinName
 item = wx.MenuItem(self, wx.NewId(), "菜单项1")
 self.AppendItem(item)
 self.Bind(wx.EVT_MENU, self.OnItem1, item)
 item = wx.MenuItem(self, wx.NewId(), "菜单项2")
 self.AppendItem(item)
 self.Bind(wx.EVT_MENU, self.OnItem2, item)
 item = wx.MenuItem(self, wx.NewId(), "菜单项3")
 self.AppendItem(item)
 self.Bind(wx.EVT_MENU, self.OnItem3, item)
 
    def OnItem1(self, event):
 print "%s 窗口中的菜单项 1 被选中了" % self.WinName
    
    def OnItem2(self, event):
 print "%s 窗口中的菜单项 2 被选中了" % self.WinName
    
    def OnItem3(self, event):
 print "%s 窗口中的菜单项 3 被选中了" % self.WinName
 
class MyWindow(wx.Window):
    def __init__(self, parent, colour):
 wx.Window.__init__(self, parent, -1)
 self.colour = colour
 self.SetBackgroundColour(colour)
 self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
 
    def OnRightDown(self, event):
 self.PopupMenu(MyPopupMenu(self.colour), event.GetPosition())

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
 wx.Frame.__init__(self, parent, id, title, size=(300, 200))
 sizer = wx.GridSizer(2, 2, 5, 5)
 sizer.Add(MyWindow(self, "blue"), 1, wx.GROW)
 sizer.Add(MyWindow(self, "yellow"), 1, wx.GROW)
 sizer.Add(MyWindow(self, "red"), 1, wx.GROW)
 sizer.Add(MyWindow(self, "green"), 1, wx.GROW)
 self.CreateStatusBar()
 self.SetSizer(sizer)
 self.Show()
 
frame=MyFrame(None, -1, "测试")
app.SetTopWindow(frame)
app.MainLoop()
 

这个例子只是单个的框架.
它被分为四个窗口. 如你在框架上点击右键,上下文菜单将会弹出. 该菜单有3个命令.

在选择它们中任何一个后,就会有一条消息发送到控制台.
它将告诉你选择了那个项目以及点击鼠标所在窗口的颜色.

此例说明了面向对象编程所具有的威力. 试想一下如果你是通过计算鼠标指针位置的方式来实现,会有多麻烦!
注意,这里的弹出菜单是作为一个新类来实现的.

向下面这样使用弹出菜单则更为优雅.
代码:
 

复制代码 代码示例:
def OnRightClick(self, event):
    #因为只是首次运行一下这段代码,所以事件只会被绑定一次
    if not hasattr(self, "popupID1"):
 self.popupID1 = wx.NewId()
 self.popupID2 = wx.NewId()
 self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
 self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
    menu = wx.Menu()
    menu.Append(self.popupID1, "One")
    menu.Append(self.popupID2, "Two")
    self.PopupMenu(menu, event.GetPosition())
    menu.Destroy()
  def OnPopupOne(self, event):
      pass
  def OnPopupTwo(self, event):
      pass
 

这段代码有一些微妙的地方需要说明一下.
这里对事件只绑定了一次. 绑定是在后面的事件表中.
如果你是在类构建器中完成的绑定,那没有问题.
但如果是在一个方法中绑定事件到处理器,那么在该方法每次调用时,都会做一次事件绑定.
这就是为什么要写一个条件判断,来确保不会因此而造成开销太大.

代码:
 

复制代码 代码示例:
if not hasattr(self, "popupID1"):
  self.popupID1 = wx.NewId()
  self.popupID2 = wx.NewId()
  self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
  self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)