1、问题背景
在使用 wxpython 开发 GUI 时,遇到了一个问题。当鼠标悬停在 BitmapButton 上时,会同时调用两个事件:
self.Bind(wx.EVT_LEAVE_WINDOW, self.onPanelMouseLeave)
self.Bind(wx.EVT_ENTER_WINDOW, self.onPanelMouseOver)
这导致了程序出现不必要的重复调用,从而产生了不期望的行为。
2、解决方案
根据答案1中的建议,问题的原因在于隐藏和显示位图时,鼠标会离开面板,从而触发 onPanelMouseLeave
事件。因此,我们只需要在 onPanelMouseLeave
事件中注释掉 self.pluginClose.Hide()
语句,即可避免重复调用事件。
修改后的代码如下:
import wxclass Plugin(wx.Panel):def __init__(self, parent, *args, **kwargs):panel = wx.Panel.__init__(self, parent, *args, **kwargs)self.colorOver = ((89,89,89))self.colorLeave = ((110,110,110))self.colorFont = ((145,145,145))self.SetBackgroundColour(self.colorLeave)self.SetForegroundColour(self.colorLeave)self.name = "Plugin"self.overPanel = 0self.overLabel = 0self.overButton = 0sizer = wx.BoxSizer(wx.VERTICAL)self.pluginName = wx.StaticText(self, -1, ' ' + self.getName())self.pluginClose = wx.BitmapButton(self, -1, wx.Bitmap('C:\Users\André Ferreira\Desktop\Tese\Código Python\SoundLog\Images\close.png'), style=wx.NO_BORDER)self.pluginClose.Hide()gs = wx.GridSizer(2, 2, 0, 0)gs.AddMany([(self.pluginName, 0, wx.ALIGN_LEFT), (self.pluginClose, 0, wx.ALIGN_RIGHT|wx.CENTER)])sizer.Add(gs, 1, wx.EXPAND)self.SetSizer(sizer)self.pluginName.Bind(wx.EVT_LEAVE_WINDOW, self.onLabelMouseLeave)self.pluginName.Bind(wx.EVT_ENTER_WINDOW, self.onLabelMouseOver)self.pluginClose.Bind(wx.EVT_BUTTON, self.onCloseMouseClick)self.Bind(wx.EVT_LEAVE_WINDOW, self.onPanelMouseLeave)self.Bind(wx.EVT_ENTER_WINDOW, self.onPanelMouseOver)def onPanelMouseOver(self, event):self.overPanel = 1self.overLabel = 0self.SetBackgroundColour(self.colorOver)self.pluginName.SetForegroundColour(self.colorFont)self.Refresh()self.pluginClose.Show()def onPanelMouseLeave(self, event):# Comment out this line to fix the issue# self.pluginClose.Hide()if self.overLabel == 0:self.overPanel = 0self.SetBackgroundColour(self.colorLeave)self.pluginName.SetForegroundColour(self.colorLeave)self.Refresh()def onLabelMouseOver(self, event):self.overPanel = 0self.overLabel = 1self.SetBackgroundColour(self.colorOver)self.pluginName.SetForegroundColour(self.colorFont)self.Refresh()self.pluginClose.Show()def onLabelMouseLeave(self, event):if self.overPanel == 0:self.overLabel = 0self.SetBackgroundColour(self.colorLeave)self.pluginName.SetForegroundColour(self.colorLeave)self.Refresh()self.pluginClose.Hide()def OnClose(self, event):self.Close()app.Destroy()def onCloseMouseClick(self, event):self.Hide()def getName(self):return self.name
修改后的代码可以正常工作,当鼠标悬停在 BitmapButton 上时,只会调用 onLabelMouseOver
事件,而不会再同时调用 onPanelMouseLeave
和 onPanelMouseOver
事件。