Wxpython:将菜单定位在工具栏按钮下

发布于 2024-07-27 21:48:02 字数 245 浏览 5 评论 0原文

我在 wx.ToolBar 中有一个 CheckLabelTool,我希望在单击鼠标时在其正下方弹出一个菜单。 我试图获取工具的位置,以便设置菜单的位置,但我尝试过的所有操作(GetEventObject、GetPosition 等)都给了我工具栏的位置,因此菜单会在工具栏下方弹出,但距离相关工具还很远。 有什么建议么? 我需要该工具具有切换和位图功能,但如果有其他东西可以更好地工作,我不会固定在 CheckLabelTool 上。

谢谢!

I have a CheckLabelTool in a wx.ToolBar and I want a menu to popup directly beneath it on mouse click. I'm trying to get the location of the tool so I can set the position of the menu, but everything I've tried (GetEventObject, GetPosition, etc) gives me the position of the toolbar, so consequently the menu pops under the toolbar, but very far from the associated tool. Any suggestions? I need the tool to have toggle and bitmap capability, but I'm not fixed on CheckLabelTool if there's something else that would work better.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

以为你会在 2024-08-03 21:48:03

阅读 wxpython.org 上有关 PopupMenu 方法的部分:

“弹出给定的菜单
指定坐标,相对于
此窗口,并返回控制时
用户已关闭菜单。 如果一个
选择菜单项后,
生成相应的菜单事件
并将照常处理。 如果
给出默认位置然后
鼠标光标的当前位置
将被使用。”

您需要绑定到您的检查工具的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()

部分代码来自 此处

Read the section on the PopupMenu method on wxpython.org:

"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."

You need to bind to the EVT_MENU event of your check tool. Once the tool button is checked, you can pop the menu up. If you don't specify the location of the popup, it will use the current position of the mouse, which is what you want.

If you want the menu to pop up at a pre-determined location that is independent of the mouse, you can get the screen location of the toolbar and add an offset

Let's look at code:

[Edit: To show how to compute the position of any point on a tool, I have modified the code to compute and display various points on the tool bar once you click a tool. The menu appears on the lower right corner of the clicked button. It works for me on Windows. I'm curious to know if it doesn't behave on other platforms.]

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()

Parts of this code come from here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文