How to tweak my tooltips in wxpython?

2020-03-02 05:47发布

问题:

I was trying to add a tooltip to show the full content of a truncated ObjectListView, until it turned out it had such a feature built-in:

I tried making my own tool tips using wx.TipWindow, wx.PopupWindow and SuperToolTip, but none of them looked as 'native' as this one.

While I'm aware of this wiki article that supposedly enables the tooltip for truncated wx.Listrctrls, I didn't really understand how to get it working. I also expect that it only works when something is truncated, whereas I'd like to be able to use it to display some more information.

I guess the SuperToolTip comes close, but when you remove the 'header' it leaves it with empty space at the top, rather than centering the text in the middle of the tooltip and making it fit.

I tried looking through the source code of ObjectListView, SuperToolTip and wxpython to try and find how tooltips are being created, but I can't really find the low level parts that make it happen.

So how can I tweak tooltips so they look more like native tooltips?

The code to generate my current popups was:

text = "I'm a popup"

class PopUp(wx.TipWindow):
    def __init__(self, parent, text):
        wx.TipWindow.__init__(self, parent, text)

class PopUp2(wx.PopupWindow):
    def __init__(self, parent, text):
        wx.PopupWindow.__init__(self, parent)
        st = wx.StaticText(self, parent, text)

# Import `from agw import supertooltip as STT`
popup3 = STT.SuperToolTip(text)

回答1:

Even if you can't create and pop up a native tooltip from scratch, you can still assign the entire ListCtrl a tooltip when you create it, and then change the text to whatever you want based on the item under the mouse pointer. It doesn't position the tooltip neatly over the list item like ObjectListView does, but I think it still accomplishes what you're asking.

    self.lc = wx.ListCtrl(self, style=wx.LC_REPORT)
    # ...
    self.lc.Bind(wx.EVT_MOTION, self.OnMouseMotion)

def OnMouseMotion(self, evt):
    pos = self.lc.ScreenToClient(wx.GetMousePosition())
    item_index, flag = self.lc.HitTest(pos)
    tip = self.lc.GetToolTip()

    if flag == wx.LIST_HITTEST_ONITEMLABEL:
        tip.SetTip('Some information about ' + self.lc.GetItemText(item_index))
    else:
        tip.SetTip('')

    evt.Skip()


回答2:

I'm not sure if we have a way to create a native Win7 tooltip yet, as you've seen wx.TipWindow looks like the tooltips from older versions of Windows, so there are probably some newer APIs that we should be using instead. Please create a ticket at trac.wxwidgets.org to find out for sure or to request the change if it's not possible some other way that I'm not thinking of at the moment.