如何多次显示 wx.TipWindow?
How can I show a wx.TipWindow multiple times?
我试图在滚轮更改 RadioBox
项目时在鼠标位置显示 wx.TipWindow
(我希望新选择的项目显示在鼠标处)。
这就是我所拥有的:
wx.TipWindow(self, self.rdb.GetString(nxt)) <- Works perfectly. Self is an instance of wx.Frame
但是,如果上面的行被调用不止一次(即,我滚动不止一次~5 次),它会不断地在彼此之上生成新的 windows。最终,程序因以下错误而崩溃:
Traceback (most recent call last):
File "C:\Users\Seth\anaconda3\envs\DLC-GPU\lib\site-packages\matplotlib\backends\backend_wx.py", line 989, in _onMouseWheel
x = evt.GetX()
AttributeError: 'MouseEvent' object has no attribute 'GetX'
我不能让它工作吗?我尝试在显示下一个之前关闭并销毁 TipWindow
,但出现同样的错误。
我曾想过“为什么不自己做”,但真烦人哈哈。
显示 wx.TipWindow
的代码块:
def MouseWheel(self, event):
assert isinstance(event, wx.MouseEvent)
whlRot = event.GetWheelRotation()
if whlRot < 0:
nxt = self.rdb.GetSelection() + 1
if nxt < self.rdb.GetCount():
self.rdb.SetSelection(nxt) # Sets the next object in the RadioBox
wx.TipWindow(self, self.rdb.GetString(nxt))
if whlRot > 0:
prv = self.rdb.GetSelection() - 1
if prv >= 0:
self.rdb.SetSelection(prv) # Sets the previous object in the RadioBox
wx.TipWindow(self, self.rdb.GetString(prv))
正如您所说的“...滚轮更改 RadioBox 项目...”但这不是单选框的本机功能,它是您通过我们看不到的代码设计的。
我假设它看起来像这样:
import wx
class RadioBoxFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'Radio Box Frame', size=(400, 400))
panel = wx.Panel(self, -1, pos=(10,10), size=(300,300), style=wx.BORDER_RAISED)
sampleList = ['Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine']
self.option=wx.RadioBox(panel, -1, "Select an option", pos=(10, 10), size=wx.DefaultSize, choices=sampleList, majorDimension=3, style=wx.RA_SPECIFY_COLS)
self.Bind(wx.EVT_RADIOBOX, self.getOption)
panel.Bind(wx.EVT_MOUSEWHEEL, self.getWheelOption)
for i in range(len(sampleList)):
self.option.SetItemToolTip(i, "Option "+sampleList[i])
self.CreateStatusBar()
self.SetStatusText("Status area")
self.Show()
def getWheelOption(self, event):
assert isinstance(event, wx.MouseEvent)
whlRot = event.GetWheelRotation()
if whlRot < 0:
nxt = self.option.GetSelection() + 1
else:
nxt = self.option.GetSelection() - 1
if nxt > self.option.GetCount() - 1:
nxt = 0
if nxt < 0:
nxt = self.option.GetCount() - 1
self.option.SetSelection(nxt) # Sets the next object in the RadioBox
txt = "Option " + self.option.GetString(nxt) + " Selected"
tw = wx.TipWindow(self, txt)
tw.SetBoundingRect(wx.Rect(1,1,1,1)) #restrict action required to cancel tipwindow
self.SetStatusText(txt)
def getOption(self, event):
state1 = self.option.GetSelection()
txt = self.option.GetString(state1)
self.SetStatusText(txt+" is Selected")
if __name__ == '__main__':
app = wx.App()
RadioBoxFrame()
app.MainLoop()
产生以下内容:
稍微玩一下这段代码,你会发现你仍然遇到同样的错误,因为在 Linux 上使用 wxPython 4.1.1,上面的代码不会给出错误。如果上述代码失败,您可能需要查看您的环境。
终于找到了不需要更新 wxPython 的答案(因为这破坏了代码中不属于我的东西)。
这是我最后做的:
if self.popUp is None:
self.popUp = wx.TipWindow(self, wht, maxLength=1000000)
else:
try: # Try is needed for if the TipWindow is closed by clicking elsewhere
self.popUp.Show(show=False) # This was the key line. For some reason, hiding the window was required before destroying
self.popUp.Destroy()
except:
pass
self.popUp = wx.TipWindow(self, wht, maxLength=1000000)
这非常有效,是我想要的结果。
我注意到 wxPython 4.1.0 和 4.1.1 之间 Windows 上的不同 TipWindow 行为。在 4.1.1 版本中,TipWIndow 在移出 BoundingRect 时不会被销毁。与上述类似的问题,但不同之处在于我仅在升级到 4.1.1 时遇到此问题。请参阅下面的片段以重现此行为 + 4.1.1 中的效果图片。有没有人有类似的经历,知道解决办法是什么?
import wx
class RadioBoxFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1)
panel = wx.Panel(self, -1, pos=(10, 10))
sampleList = ['Zero', 'One', 'Two']
self.option = wx.RadioBox(panel, -1, "Select an option", pos=(10, 10),
size=wx.DefaultSize, choices=sampleList,
majorDimension=3)
self.Bind(wx.EVT_RADIOBOX, self.getOption)
panel.Bind(wx.EVT_MOUSEWHEEL, self.getWheelOption)
self.Show()
def getWheelOption(self, event):
whlRot = event.GetWheelRotation()
if whlRot < 0:
nxt = self.option.GetSelection() + 1
else:
nxt = self.option.GetSelection() - 1
if nxt > self.option.GetCount() - 1:
nxt = 0
if nxt < 0:
nxt = self.option.GetCount() - 1
self.option.SetSelection(nxt)
txt = "Option " + self.option.GetString(nxt) + " Selected"
tw = wx.TipWindow(self, txt)
tw.SetBoundingRect(wx.Rect(1, 1, 1, 1))
def getOption(self, event):
state1 = self.option.GetSelection()
if __name__ == '__main__':
app = wx.App()
RadioBoxFrame()
app.MainLoop()
我试图在滚轮更改 RadioBox
项目时在鼠标位置显示 wx.TipWindow
(我希望新选择的项目显示在鼠标处)。
这就是我所拥有的:
wx.TipWindow(self, self.rdb.GetString(nxt)) <- Works perfectly. Self is an instance of wx.Frame
但是,如果上面的行被调用不止一次(即,我滚动不止一次~5 次),它会不断地在彼此之上生成新的 windows。最终,程序因以下错误而崩溃:
Traceback (most recent call last):
File "C:\Users\Seth\anaconda3\envs\DLC-GPU\lib\site-packages\matplotlib\backends\backend_wx.py", line 989, in _onMouseWheel
x = evt.GetX()
AttributeError: 'MouseEvent' object has no attribute 'GetX'
我不能让它工作吗?我尝试在显示下一个之前关闭并销毁 TipWindow
,但出现同样的错误。
我曾想过“为什么不自己做”,但真烦人哈哈。
显示 wx.TipWindow
的代码块:
def MouseWheel(self, event):
assert isinstance(event, wx.MouseEvent)
whlRot = event.GetWheelRotation()
if whlRot < 0:
nxt = self.rdb.GetSelection() + 1
if nxt < self.rdb.GetCount():
self.rdb.SetSelection(nxt) # Sets the next object in the RadioBox
wx.TipWindow(self, self.rdb.GetString(nxt))
if whlRot > 0:
prv = self.rdb.GetSelection() - 1
if prv >= 0:
self.rdb.SetSelection(prv) # Sets the previous object in the RadioBox
wx.TipWindow(self, self.rdb.GetString(prv))
正如您所说的“...滚轮更改 RadioBox 项目...”但这不是单选框的本机功能,它是您通过我们看不到的代码设计的。
我假设它看起来像这样:
import wx
class RadioBoxFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'Radio Box Frame', size=(400, 400))
panel = wx.Panel(self, -1, pos=(10,10), size=(300,300), style=wx.BORDER_RAISED)
sampleList = ['Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine']
self.option=wx.RadioBox(panel, -1, "Select an option", pos=(10, 10), size=wx.DefaultSize, choices=sampleList, majorDimension=3, style=wx.RA_SPECIFY_COLS)
self.Bind(wx.EVT_RADIOBOX, self.getOption)
panel.Bind(wx.EVT_MOUSEWHEEL, self.getWheelOption)
for i in range(len(sampleList)):
self.option.SetItemToolTip(i, "Option "+sampleList[i])
self.CreateStatusBar()
self.SetStatusText("Status area")
self.Show()
def getWheelOption(self, event):
assert isinstance(event, wx.MouseEvent)
whlRot = event.GetWheelRotation()
if whlRot < 0:
nxt = self.option.GetSelection() + 1
else:
nxt = self.option.GetSelection() - 1
if nxt > self.option.GetCount() - 1:
nxt = 0
if nxt < 0:
nxt = self.option.GetCount() - 1
self.option.SetSelection(nxt) # Sets the next object in the RadioBox
txt = "Option " + self.option.GetString(nxt) + " Selected"
tw = wx.TipWindow(self, txt)
tw.SetBoundingRect(wx.Rect(1,1,1,1)) #restrict action required to cancel tipwindow
self.SetStatusText(txt)
def getOption(self, event):
state1 = self.option.GetSelection()
txt = self.option.GetString(state1)
self.SetStatusText(txt+" is Selected")
if __name__ == '__main__':
app = wx.App()
RadioBoxFrame()
app.MainLoop()
产生以下内容:
稍微玩一下这段代码,你会发现你仍然遇到同样的错误,因为在 Linux 上使用 wxPython 4.1.1,上面的代码不会给出错误。如果上述代码失败,您可能需要查看您的环境。
终于找到了不需要更新 wxPython 的答案(因为这破坏了代码中不属于我的东西)。
这是我最后做的:
if self.popUp is None:
self.popUp = wx.TipWindow(self, wht, maxLength=1000000)
else:
try: # Try is needed for if the TipWindow is closed by clicking elsewhere
self.popUp.Show(show=False) # This was the key line. For some reason, hiding the window was required before destroying
self.popUp.Destroy()
except:
pass
self.popUp = wx.TipWindow(self, wht, maxLength=1000000)
这非常有效,是我想要的结果。
我注意到 wxPython 4.1.0 和 4.1.1 之间 Windows 上的不同 TipWindow 行为。在 4.1.1 版本中,TipWIndow 在移出 BoundingRect 时不会被销毁。与上述类似的问题,但不同之处在于我仅在升级到 4.1.1 时遇到此问题。请参阅下面的片段以重现此行为 + 4.1.1 中的效果图片。有没有人有类似的经历,知道解决办法是什么?
import wx
class RadioBoxFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1)
panel = wx.Panel(self, -1, pos=(10, 10))
sampleList = ['Zero', 'One', 'Two']
self.option = wx.RadioBox(panel, -1, "Select an option", pos=(10, 10),
size=wx.DefaultSize, choices=sampleList,
majorDimension=3)
self.Bind(wx.EVT_RADIOBOX, self.getOption)
panel.Bind(wx.EVT_MOUSEWHEEL, self.getWheelOption)
self.Show()
def getWheelOption(self, event):
whlRot = event.GetWheelRotation()
if whlRot < 0:
nxt = self.option.GetSelection() + 1
else:
nxt = self.option.GetSelection() - 1
if nxt > self.option.GetCount() - 1:
nxt = 0
if nxt < 0:
nxt = self.option.GetCount() - 1
self.option.SetSelection(nxt)
txt = "Option " + self.option.GetString(nxt) + " Selected"
tw = wx.TipWindow(self, txt)
tw.SetBoundingRect(wx.Rect(1, 1, 1, 1))
def getOption(self, event):
state1 = self.option.GetSelection()
if __name__ == '__main__':
app = wx.App()
RadioBoxFrame()
app.MainLoop()