[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    Re: [PyQt] Show tooltip onto QLabel
From:       Maurizio Berti <maurizio.berti () gmail ! com>
Date:       2019-01-22 19:00:04
Message-ID: CAPn+-XTF=-N5FWikUkb231W=p8uezsEfmDQ9Q=ooV_Df0q0Jhg () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Glad I could help!
I've never used HoverEvents, but if it suits your needs, that's ok :-)

Yes, another issue with QToolTip is the delay after their event is called.
Since Qt5 it can be customized, though, by setting a QProxyStyle that
returns the timeout in milliseconds when SH_ToolTip_WakeUpDelay styleHint
is requested.
This is a small example that allows you to set a 0 timeout for specific
widgets:

class MyStyle(QtWidgets.QProxyStyle):
    toolTipTimeouts = {}
    def styleHint(self, hint, option, widget, returnData):
        if hint == QtWidgets.QStyle.SH_ToolTip_WakeUpDelay:
            try:
                return self.toolTipTimeouts[widget]
            except:
                pass
        return QtWidgets.QProxyStyle.styleHint(self, hint, option, widget,
returnData)

class MyWindow(QtWidgets.QMainWindow):
    def __init__(self):
        [...]
        self.widget = SomeWidget()
        self.style().toolTipTimeouts[self.widget] = 0
        #optional, if you need to remove widgets at a certain point,
        #allowing the garbage collector to free up memory
        self.widget.destroyed.connect(self.style().toolTipTimeouts.pop)

app = QtWidgets.QApplication(sys.argv)
app.setStyle(MyStyle())

In this way the QProxyStyle will immediately call the QEvent.ToolTip for
the specified widgets.

Maurizio

Il giorno mar 22 gen 2019 alle ore 16:21 Tong Zhang <warriorlance@gmail.com>
ha scritto:

> Thanks, Maurizio! I've got what I want from your message, BTW, I used
> hover event to trig the help message to show on a textedit, since I
> found tooltip event responses a little bit slower than I want, maybe
> there is someway to speed up.
>
> Tong
>
> On 1/21/19 6:40 PM, Maurizio Berti wrote:
> > Using standard tooltips might be an issue in some (not so special)
> > cases, as QToolTip events are strictly related to the widget events, so
> > you'll need to install an eventFilter on every single widget you'll want
> > the behavior you ask about.
> > A simple implementation would be something like this:
> >
> >      def __init__(self, *args, **kwargs):
> >          [...]
> >          self.toolTipWidget = QtWidgets.QLabel()
> >          [...]
> >          self.someWidget = SomeWidget()
> >          self.someWidget.setToolTip('I am a tooltip!')
> >          self.someWidget.installEventFilter(self)
> >          [...]
> >
> >      def eventFilter(self, source, event):
> >          if event.type() == QtCore.QEvent.ToolTip:
> >              self.toolTipWidget.setText(source.toolTip())
> >          return QtWidgets.QWidget.eventFilter(self, source, event)
> >
> > On the other hand, I'd suggest to use the StatusTip instead of the
> > ToolTip: it's something I've successfully used for something similar to
> > your needs: in this way you can keep the StatusTip for "simple" tooltip
> > text and the ToolTips for further customized messages, as they also
> > allow rich text content.
> > Here's a small example:
> >
> >      def __init__(self, *args, **kwargs):
> >          [...]
> >          self.toolTipWidget = QtWidgets.QLabel()
> >          [...]
> >          self.someWidget = SomeWidget()
> >          self.someWidget.setStatusTip('I am a statustip!')
> >          [...]
> >
> >      def event(self, event):
> >          if event.type() == QtCore.QEvent.StatusTip and event.tip():
> >              self.toolTipWidget.setText(event.tip())
> >          return QtWidgets.QWidget.event(self, event)
> >
> > Note that here I used the setStatusTip() method instead of the
> > setToolTip() one.
> > Obviously, if you're using Designer you'll set the StatusTip property
> > from there, instead of the ToolTip property.
> >
> > How does it work?
> > Usually the StatusTip is only used on a QMainWindow with a QStatusBar
> > installed, but, interestingly enough, the event() method of *any* widget
> > can be used to catch /any/ StatusTip event called from both that widget
> > /and/ its children.
> >
> > In both cases you'd better think about a way to "clear" the tool/status
> > tip, as leaving it there might be confusing.
> > If you don't have too many widgets, the eventFilter way might be a good
> > solution, as you can also catch the QEvent.Leave event type to hide the
> > "tooltip" by clearing the label text, otherwise it's probably
> > better using a QTimer on the parent widget or the label, and set it as
> > singleShot (don't use the static method, as it could hide a new
> > statustip activated in the meantime), then connect it to something like
> > lambda: self.toolTipWidget.setText('')whenever you catch the StatusTip
> > event.
> >
> > If for some reason you'll need to stick with ToolTips, there's a
> > solution anyway.
> > If all widgets already have their tooltips, and the layout is static and
> > permanent once the main parent widget is being instantiated, just use
> > the children() iterator and check for both isWidgetType() and toolTip()
> > contents: if those condition match, install the eventFilter; if the
> > layout is dynamic instead, use the childEvent method on the parent and
> > check for QEvent.childAdded and QEvent.childRemoved events, then use
> > installEventFilter or removeEventFilter respectively.
> >
> > Regards,
> > Maurizio
> >
> >
> > Il giorno lun 21 gen 2019 alle ore 23:22 Tong Zhang
> > <warriorlance@gmail.com <mailto:warriorlance@gmail.com>> ha scritto:
> >
> >     Hello,
> >
> >     Can I show the tooltip of some widget onto a QLabel? e.g. Tooltip
> >     will show when I move the mouse onto the pushbutton, how about show
> >     the tooltip on another widget, say label?
> >
> >     Thanks,
> >     Tong
> >     _______________________________________________
> >     PyQt mailing list PyQt@riverbankcomputing.com
> >     <mailto:PyQt@riverbankcomputing.com>
> >     https://www.riverbankcomputing.com/mailman/listinfo/pyqt
> >
> >
> >
> > --
> > È difficile avere una convinzione precisa quando si parla delle ragioni
> > del cuore. - "Sostiene Pereira", Antonio Tabucchi
> > http://www.jidesk.net
>


-- 
È difficile avere una convinzione precisa quando si parla delle ragioni del
cuore. - "Sostiene Pereira", Antonio Tabucchi
http://www.jidesk.net

[Attachment #5 (text/html)]

<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div \
dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Glad I could \
help!</div><div dir="ltr">I&#39;ve never used HoverEvents, but if it suits your \
needs, that&#39;s ok :-)</div><div dir="ltr"><br></div><div dir="ltr">Yes, another \
issue with QToolTip is the delay after their event is called.<br>Since Qt5 it can be \
customized, though, by setting a QProxyStyle that returns the timeout in milliseconds \
when SH_ToolTip_WakeUpDelay styleHint is requested.</div><div>This is a small example \
that allows you to set a 0 timeout for specific \
widgets:</div><div><br></div><div><div><font face="monospace, monospace">class \
MyStyle(QtWidgets.QProxyStyle):</font></div><div><font face="monospace, monospace">   \
toolTipTimeouts = {}</font></div><div><font face="monospace, monospace">      def \
styleHint(self, hint, option, widget, returnData):</font></div><div><font \
face="monospace, monospace">            if hint == \
QtWidgets.QStyle.SH_ToolTip_WakeUpDelay:<br></font></div><div><font face="monospace, \
monospace">                  try:</font></div><div><font face="monospace, monospace"> \
return self.</font><span \
style="font-family:monospace,monospace">toolTipTimeouts[widget]</span></div><div><span \
style="font-family:monospace,monospace">                  \
except:</span></div><div><font face="monospace, monospace">                        \
pass</font></div><div><font face="monospace, monospace">            return \
QtWidgets.QProxyStyle.styleHint(self, hint, option, widget,  </font><span \
style="font-family:monospace,monospace">returnData</span><font face="monospace, \
monospace">)</font></div></div><div><font face="monospace, \
monospace"><br></font></div><div><font face="monospace, monospace">class \
MyWindow(QtWidgets.QMainWindow):</font></div><div><font face="monospace, monospace">  \
def __init__(self):</font></div><div><font face="monospace, monospace">            \
[...]</font></div><div><font face="monospace, monospace">            self.widget = \
SomeWidget()</font></div><div><font face="monospace, monospace">            \
self.style()</font><font face="monospace, monospace">.</font><span \
style="font-family:monospace,monospace">toolTipTimeouts[</span><font face="monospace, \
monospace">self.widget] = 0</font><br></div><div><font face="monospace, monospace">   \
#optional, if you need to remove widgets at a certain point,  </font></div><div><font \
face="monospace, monospace">            #allowing the garbage collector to free up \
memory</font></div><div><font face="monospace, monospace">            \
self.widget.destroyed.connect(self.style().toolTipTimeouts.pop)</font></div><div><font \
face="monospace, monospace"><br></font></div><div><div><font face="monospace, \
monospace">app = QtWidgets.QApplication(sys.argv)</font></div><div><font \
face="monospace, monospace">app.setStyle(MyStyle())</font></div></div><div><font \
face="monospace, monospace"><br></font></div><div><font face="arial, helvetica, \
sans-serif">In this way the QProxyStyle will immediately call the QEvent.ToolTip for \
the specified widgets.</font></div><div><font face="arial, helvetica, \
sans-serif"><br></font></div><div><font face="arial, helvetica, \
sans-serif">Maurizio</font></div></div></div></div></div></div></div></div></div></div><br><div \
class="gmail_quote"><div dir="ltr" class="gmail_attr">Il giorno mar 22 gen 2019 alle \
ore 16:21 Tong Zhang &lt;<a \
href="mailto:warriorlance@gmail.com">warriorlance@gmail.com</a>&gt; ha \
scritto:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px \
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Thanks, Maurizio! \
I&#39;ve got what I want from your message, BTW, I used <br> hover event to trig the \
help message to show on a textedit, since I <br> found tooltip event responses a \
little bit slower than I want, maybe <br> there is someway to speed up.<br>
<br>
Tong<br>
<br>
On 1/21/19 6:40 PM, Maurizio Berti wrote:<br>
&gt; Using standard tooltips might be an issue in some (not so special) <br>
&gt; cases, as QToolTip events are strictly related to the widget events, so <br>
&gt; you&#39;ll need to install an eventFilter on every single widget you&#39;ll want \
<br> &gt; the behavior you ask about.<br>
&gt; A simple implementation would be something like this:<br>
&gt; <br>
&gt;         def __init__(self, *args, **kwargs):<br>
&gt;                [...]<br>
&gt;               self.toolTipWidget = QtWidgets.QLabel()<br>
&gt;                [...]<br>
&gt;                self.someWidget = SomeWidget()<br>
&gt;                self.someWidget.setToolTip(&#39;I am a tooltip!&#39;)<br>
&gt;                self.someWidget.installEventFilter(self)<br>
&gt;                [...]<br>
&gt; <br>
&gt;         def eventFilter(self, source, event):<br>
&gt;               if event.type() == QtCore.QEvent.ToolTip:<br>
&gt;                     self.toolTipWidget.setText(source.toolTip())<br>
&gt;               return QtWidgets.QWidget.eventFilter(self, source, event)<br>
&gt; <br>
&gt; On the other hand, I&#39;d suggest to use the StatusTip instead of the <br>
&gt; ToolTip: it&#39;s something I&#39;ve successfully used for something similar to \
<br> &gt; your needs: in this way you can keep the StatusTip for &quot;simple&quot; \
tooltip <br> &gt; text and the ToolTips for further customized messages, as they also \
<br> &gt; allow rich text content.<br>
&gt; Here&#39;s a small example:<br>
&gt; <br>
&gt;         def __init__(self, *args, **kwargs):<br>
&gt;                [...]<br>
&gt;               self.toolTipWidget = QtWidgets.QLabel()<br>
&gt;                [...]<br>
&gt;               self.someWidget = SomeWidget()<br>
&gt;                self.someWidget.setStatusTip(&#39;I am a statustip!&#39;)<br>
&gt;               [...]<br>
&gt; <br>
&gt;         def event(self, event):<br>
&gt;               if event.type() == QtCore.QEvent.StatusTip and event.tip():<br>
&gt;                     self.toolTipWidget.setText(event.tip())<br>
&gt;               return QtWidgets.QWidget.event(self, event)<br>
&gt; <br>
&gt; Note that here I used the setStatusTip() method instead of the <br>
&gt; setToolTip() one.<br>
&gt; Obviously, if you&#39;re using Designer you&#39;ll set the StatusTip property \
<br> &gt; from there, instead of the ToolTip property.<br>
&gt; <br>
&gt; How does it work?<br>
&gt; Usually the StatusTip is only used on a QMainWindow with a QStatusBar <br>
&gt; installed, but, interestingly enough, the event()  method of *any* widget <br>
&gt; can be used to catch /any/  StatusTip event called from both that widget <br>
&gt; /and/  its  children.<br>
&gt; <br>
&gt; In both cases you&#39;d better think about a way to &quot;clear&quot; the \
tool/status <br> &gt; tip, as leaving it there might be confusing.<br>
&gt; If you don&#39;t have too many widgets, the eventFilter way might be a good <br>
&gt; solution, as you can also catch the QEvent.Leave event type to hide the <br>
&gt; &quot;tooltip&quot; by clearing the label text, otherwise it&#39;s probably <br>
&gt; better  using a QTimer on the parent widget or the label, and set it as <br>
&gt; singleShot (don&#39;t use the static method, as it could hide a new <br>
&gt; statustip activated in the meantime), then connect it to something like <br>
&gt; lambda: self.toolTipWidget.setText(&#39;&#39;)whenever you catch the StatusTip \
<br> &gt; event.<br>
&gt; <br>
&gt; If for some reason you&#39;ll need to stick with ToolTips, there&#39;s a <br>
&gt; solution anyway.<br>
&gt; If all widgets already have their tooltips, and the layout is static and <br>
&gt; permanent once the main parent widget is being instantiated, just use <br>
&gt; the children() iterator and check for both isWidgetType() and toolTip() <br>
&gt; contents: if those condition match, install the eventFilter; if the <br>
&gt; layout is dynamic instead, use the childEvent method on the parent and <br>
&gt; check for QEvent.childAdded and QEvent.childRemoved events, then use <br>
&gt; installEventFilter or removeEventFilter respectively.<br>
&gt; <br>
&gt; Regards,<br>
&gt; Maurizio<br>
&gt; <br>
&gt; <br>
&gt; Il giorno lun 21 gen 2019 alle ore 23:22 Tong Zhang <br>
&gt; &lt;<a href="mailto:warriorlance@gmail.com" \
target="_blank">warriorlance@gmail.com</a> &lt;mailto:<a \
href="mailto:warriorlance@gmail.com" \
target="_blank">warriorlance@gmail.com</a>&gt;&gt; ha scritto:<br> &gt; <br>
&gt;        Hello,<br>
&gt; <br>
&gt;        Can I show the tooltip of some widget onto a QLabel? e.g. Tooltip<br>
&gt;        will show when I move the mouse onto the pushbutton, how about show<br>
&gt;        the tooltip on another widget, say label?<br>
&gt; <br>
&gt;        Thanks,<br>
&gt;        Tong<br>
&gt;        _______________________________________________<br>
&gt;        PyQt mailing list <a href="mailto:PyQt@riverbankcomputing.com" \
target="_blank">PyQt@riverbankcomputing.com</a><br> &gt;        &lt;mailto:<a \
href="mailto:PyQt@riverbankcomputing.com" \
target="_blank">PyQt@riverbankcomputing.com</a>&gt;<br> &gt;        <a \
href="https://www.riverbankcomputing.com/mailman/listinfo/pyqt" rel="noreferrer" \
target="_blank">https://www.riverbankcomputing.com/mailman/listinfo/pyqt</a><br> &gt; \
<br> &gt; <br>
&gt; <br>
&gt; -- <br>
&gt; È difficile avere una convinzione precisa quando si parla delle ragioni <br>
&gt; del cuore. - &quot;Sostiene Pereira&quot;, Antonio Tabucchi<br>
&gt; <a href="http://www.jidesk.net" rel="noreferrer" \
target="_blank">http://www.jidesk.net</a><br> </blockquote></div><br \
clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature">È difficile \
avere una convinzione precisa quando si parla delle ragioni del cuore. - \
&quot;Sostiene Pereira&quot;, Antonio Tabucchi<br><a href="http://www.jidesk.net" \
target="_blank">http://www.jidesk.net</a></div>


[Attachment #6 (text/plain)]

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
https://www.riverbankcomputing.com/mailman/listinfo/pyqt


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic