Код был выполнен на Python 3.13.5.
Пример кода Toy
Код: Выделить всё
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Small toy example reproducing the tooltip problem
"""
import wx
class MyFrame(wx.Frame):
def __init__(self):
# Ensure a wx.App exists. Some callers may import this module
# and instantiate MyFrame before an App is created; guard against that.
try:
app_exists = bool(wx.GetApp())
except Exception:
app_exists = False
if not app_exists:
self._created_app = True
# Create a non-redirected App but do NOT start the MainLoop here.
self._app = wx.App(False)
else:
self._created_app = False
wx.Frame.__init__(self, None, title="Debug Tooltips with Submenus", size=(400, 300))
# Create status bar
self.CreateStatusBar()
self.SetStatusText("Ready. Right-click to open the menu.")
panel = wx.Panel(self)
panel.SetBackgroundColour(wx.Colour(200, 200, 200))
panel.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
sizer = wx.BoxSizer(wx.VERTICAL)
label = wx.StaticText(panel, label="Right-click the window to open the menu with submenus")
sizer.Add(label, 0, wx.ALL, 10)
panel.SetSizer(sizer)
def on_right_click(self, event):
menu = wx.Menu()
menu.Bind(wx.EVT_MENU_HIGHLIGHT, self.on_menu_highlight)
menu.Bind(wx.EVT_MENU_CLOSE, self.on_menu_close)
# Simple item (no submenu)
simple_item = wx.MenuItem(menu, wx.NewId(), "Simple Option", "This is a simple tooltip without submenu")
menu.Append(simple_item)
menu.AppendSeparator()
# Submenu with options
sub_menu = wx.Menu()
sub_menu.Bind(wx.EVT_MENU_HIGHLIGHT, self.on_menu_highlight)
sub_item_1 = wx.MenuItem(sub_menu, wx.NewId(), "Sub Option 1", "Tooltip for sub-option 1")
sub_menu.Append(sub_item_1)
sub_item_2 = wx.MenuItem(sub_menu, wx.NewId(), "Sub Option 2", "Tooltip for sub-option 2")
sub_menu.Append(sub_item_2)
sub_item_3 = wx.MenuItem(sub_menu, wx.NewId(), "Sub Option 3", "Tooltip for sub-option 3")
sub_menu.Append(sub_item_3)
# Add submenu to the main menu
sub_menu_item = wx.MenuItem(menu, wx.NewId(), "Submenu", "Submenu options", wx.ITEM_NORMAL, sub_menu)
menu.Append(sub_menu_item)
self.PopupMenu(menu, event.GetPosition())
menu.Destroy()
def on_menu_highlight(self, event):
"""Show the menu item's help string in the status bar."""
try:
menu = event.GetMenu()
if not menu:
return
# Find the MenuItem first; GetHelpString will assert if item doesn't exist
item = None
if hasattr(menu, 'FindItem'):
try:
item = menu.FindItem(event.GetId())
except Exception:
item = None
if not item and hasattr(menu, 'FindItemById'):
try:
item = menu.FindItemById(event.GetId())
except Exception:
item = None
if not item:
# No corresponding MenuItem in this menu (e.g. hovering a submenu label)
self.SetStatusText("")
print(f"No MenuItem for ID: {event.GetId()}")
return
# Prefer the MenuItem's help getter
help_text = None
if hasattr(item, 'GetHelp'):
help_text = item.GetHelp()
elif hasattr(item, 'GetHelpString'):
help_text = item.GetHelpString()
else:
# Fallback: attempt menu.GetHelpString safely
try:
help_text = menu.GetHelpString(event.GetId())
except Exception:
help_text = None
if help_text:
self.SetStatusText(help_text)
print(f"Help text found: {help_text}")
else:
self.SetStatusText("")
print(f"No help text for MenuItem ID: {event.GetId()}")
except Exception as e:
print(f"Error in on_menu_highlight: {e}")
def on_menu_close(self, event):
"""Clear the status bar when the menu closes."""
self.SetStatusText("")
if __name__ == '__main__':
app = wx.App()
frame = MyFrame()
frame.Show()
app.MainLoop()
Подсказка отображается для меню, не имеющих подменю.

Однако для меню, имеющих подменю, и для элементов в этих подменю, всплывающая подсказка не отображается, как вы можете видеть ниже.

Чего я хочу
Я хотел бы знать, есть ли простой способ получить всплывающую подсказку для подменю в wxPython отображаться в строке состояния.
Примечание
Имейте в виду, что я пробовал и другие варианты, но ни один из них пока не увенчался успехом. Однако в моем основном приложении случается, что в некоторых подменю отображаются всплывающие подсказки, но только для параметров подменю, которые имеют те же идентификаторы, что и некоторые из них, которые я ранее определил в основной строке меню. Однако мне не удалось воспроизвести такое поведение в примере кода Toy. Но не все подменю должны находиться в строке главного меню, поэтому этот обходной путь мне не подходит.
Подробнее здесь: https://stackoverflow.com/questions/798 ... n-applicat