我在wx.ToolBar中有一个CheckLabelTool,我想要一个菜单在鼠标点击下直接弹出它.我正在尝试获取工具的位置,以便我可以设置菜单的位置,但我尝试过的所有东西(GetEventObject,GetPosition等)都给了我工具栏的位置,因此菜单弹出工具栏下方,但距离相关工具很远.有什么建议?我需要该工具具有切换和位图功能,但我没有修复CheckLabelTool,如果还有其他更好的方法.
谢谢!
解决方法:
阅读wxpython.org上关于PopupMenu方法的部分:
“Pops up the given menu at the
specified coordinates, relative to
this window, and returns control when
the user has dismissed the menu. If a
menu item is selected, the
corresponding menu event is generated
and will be processed as usual. If the
default position is given then the
current position of the mouse cursor
will be used.”
您需要绑定到检查工具的EVT_MENU事件.选中工具按钮后,您可以弹出菜单.如果您没有指定弹出窗口的位置,它将使用鼠标的当前位置,这就是您想要的.
如果您希望菜单弹出一个独立于鼠标的预定位置,您可以获取工具栏的屏幕位置并添加偏移量
我们来看看代码:
[编辑:为了显示如何计算工具上任何点的位置,我已经修改了代码,以便在单击工具后计算并显示工具栏上的各个点.菜单显示在单击按钮的右下角.它适用于Windows.我很想知道它是否在其他平台上没有表现.]
import wx
class ViewApp(wx.App):
def OnInit(self):
self.frame = ToolFrame(None, -1, "Test App")
self.frame.Show(True)
return True
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())
def OnMinimize(self, event):
self.parent.Iconize()
class ToolFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(350, 250))
self.toolbar = self.CreateToolBar()
self.tool_id = wx.NewId()
for i in range(3):
tool_id = wx.NewId()
self.toolbar.AddCheckLabelTool(tool_id, 'Tool', wx.EmptyBitmap(10,10))
self.toolbar.Bind(wx.EVT_MENU, self.OnTool, id=tool_id)
self.toolbar.Realize()
self.Centre()
self.Show()
def OnTool(self, event):
if event.IsChecked():
# Get the position of the toolbar relative to
# the frame. This will be the upper left corner of the first tool
bar_pos = self.toolbar.GetScreenPosition()-self.GetScreenPosition()
# This is the position of the tool along the tool bar (1st, 2nd, 3rd, etc...)
tool_index = self.toolbar.GetToolPos(event.GetId())
# Get the size of the tool
tool_size = self.toolbar.GetToolSize()
# This is the upper left corner of the clicked tool
upper_left_pos = (bar_pos[0]+tool_size[0]*tool_index, bar_pos[1])
# Menu position will be in the lower right corner
lower_right_pos = (bar_pos[0]+tool_size[0]*(tool_index+1), bar_pos[1]+tool_size[1])
# Show upper left corner of first tool in black
dc = wx.WindowDC(self)
dc.SetPen(wx.Pen("BLACK", 4))
dc.DrawCircle(bar_pos[0], bar_pos[1], 4)
# Show upper left corner of this tool in blue
dc.SetPen(wx.Pen("BLUE", 4))
dc.DrawCircle(upper_left_pos[0], upper_left_pos[1], 4)
# Show lower right corner of this tool in green
dc.SetPen(wx.Pen("GREEN", 4))
dc.DrawCircle(lower_right_pos[0], lower_right_pos[1], 4)
# Correct for the position of the tool bar
menu_pos = (lower_right_pos[0]-bar_pos[0],lower_right_pos[1]-bar_pos[1])
# Pop up the menu
self.PopupMenu(MyPopupMenu(self), menu_pos)
if __name__ == "__main__":
app = ViewApp(0)
app.MainLoop()
此代码的部分内容来自here.