如何在wxpython中为StaticBitmap创建悬停效果?

4 投票
2 回答
4370 浏览
提问于 2025-04-15 14:17

我想在静态位图上创建一个悬停效果——当鼠标光标在位图上时,显示一张图片;如果不在上面,就显示另一张图片。这是个简单的程序(在按钮上效果很好)。不过,静态位图并不会发出 EVT_WINDOW_ENTER 和 EVT_WINDOW_LEAVE 这些事件。

我可以使用 EVT_MOTION 事件。如果在光标刚好在图片边缘的时候切换图片,有时切换就会失效。(主要是当光标快速移动过边缘时)。

示例代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx

def onWindow(event):
    print "window event:", event.m_x, event.m_y

def onMotion(event):
    print "motion event:", event.m_x, event.m_y

app = wx.App()

imageA = wx.Image("b.gif", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
imageB = wx.Image("a.gif", wx.BITMAP_TYPE_ANY).ConvertToBitmap()

frame = wx.Frame(None, wx.ID_ANY, title="Hover effect", size=(100+imageA.GetWidth(), 100+imageA.GetHeight()))

w = wx.Window(frame)
bmp = wx.StaticBitmap(w, -1, imageA, (50, 50), (imageA.GetWidth(), imageA.GetHeight()))
bmp.Bind(wx.EVT_MOTION, onMotion) 
bmp.Bind(wx.EVT_ENTER_WINDOW, onWindow)
bmp.Bind(wx.EVT_LEAVE_WINDOW, onWindow)

frame.Show()
app.MainLoop()

2 个回答

0

在wxStaticBitmap的实现中可能存在一些问题,不过如果wxBitmapButton可以正常工作的话,你可以用它来达到相同的效果,而且代码会更简洁。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx

app = wx.App()

frame = wx.Frame(None, wx.ID_ANY, title="Hover effect")
w = wx.Window(frame)
c = wx.BitmapButton(w, -1, wx.EmptyBitmap(25,25), style = wx.NO_BORDER)
c.SetBitmapHover(wx.EmptyBitmap(3,3))
frame.Show()

app.MainLoop()
1

看起来这是一个wxGTK的错误,在Windows上,ENTER和LEAVE事件工作得很好。你应该把这个问题告诉核心开发者,最好的地方就是他们的错误追踪系统。我觉得这个问题不应该让你去绕着走。

我发现GenericButtons在wxGTK上没有这个问题,所以你可以先用这个,直到StaticBitmap修复好为止。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx
from wx.lib import buttons

def onWindow(event):
    print "window event:", event.m_x, event.m_y

def onMotion(event):
    print "motion event:", event.m_x, event.m_y

app = wx.App()

imageA = wx.Image("b.gif", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
imageB = wx.Image("a.gif", wx.BITMAP_TYPE_ANY).ConvertToBitmap()

frame = wx.Frame(None, wx.ID_ANY, title="Hover effect", size=(100+imageA.GetWidth(), 100+imageA.GetHeight()))

w = wx.Window(frame)
#bmp = wx.StaticBitmap(w, -1, imageA, (50, 50), (imageA.GetWidth(), imageA.GetHeight()))
bmp = buttons.GenBitmapButton(w, -1, imageA, style=wx.BORDER_NONE)
#bmp.Bind(wx.EVT_MOTION, onMotion)
bmp.Bind(wx.EVT_ENTER_WINDOW, onWindow)
bmp.Bind(wx.EVT_LEAVE_WINDOW, onWindow)

frame.Show()
app.MainLoop()

撰写回答