现在对于这个过程还有一个疑问,就是它是如何定时消失掉的呢? QTooltip 
QApplication会把延时未动鼠标的事件
QEvent::ToolTip发送到 QWidget..
然后QWidget在事件中判断!
d->QTooltip.isEmpty()是否为空.
空的话就ignore这个事件.
非空就通过QHelpEvent得到鼠标坐标.(static_cast<QHelpEvent*>(event)->globalPos())并
显示出来.
[size=; FONT-SIZE: 9pt,9pt]
[font='YaHei Consolas Hybrid']可以不定义类对象,而直接使用类的成员函数,一般使用静态成员函数,不是thiscall调用.所以也不需要有对象的this指针. [size=; FONT-SIZE: 9pt,9pt]
[font='YaHei Consolas Hybrid']Qt 的tool tip今天要给我做的qt控件加个tooltip,嗯,应该不难的。不过,还是先把tooltip的来龙去脉弄清楚先的。 
QEvent::ToolTip的前端.来自MouseMove中的定时器QApplication中有一个叫作
toolTipWakeUp的定时器,当鼠标移动到某个QWidget上一段时间不动后它便会被触发。当鼠标离此QWidget时,它便会被停止。
有MouseMove才能触发该定时器.例如在
其他触发定时器关闭的动作后
没有移动鼠标,那么定时器就没有启动.
每次MouseMove重新设置定时器.
定时器时间设为20呢?每次都达不到
相关代码在 
QApplication::notify 函数中:
//处理QEvent::MouseMove消息,
//在鼠标移动事件里,每次都重新设定WakeUp定时器(因为移动了)
//在鼠标其他事件中,每次都停止WakeUp定时器(因为有其他鼠标事件产生了)
//在WakeUp定时器响应中,关闭此定时器,开启FallAsleep定时器,
//针对这个定时器id,生成事件QEvent::ToolTip.发送到QWidget上
//并且启用FallAsleep定时器用于控制ToolTip显示时长,此时d->toolTipFallAsleep.isActive()为激活状态
//鼠标再移动的话,激活的是20ms定时器,而20ms过小,都不会得到及时的处理而阻断了该定时器的功能?(因为已经显示出来了)
//而在FallAsleep响应中,关闭定时器,并且关闭Tooltip的显示(没有).然后开始新一轮的响应了.
//那么这个ToolTip显示是如何被其他事件阻断的呢?使定时器睡眠就能关闭ToolTip的显示?
//是在那个20ms的定时器里,先判断FallAsleep是否激活,然后判断一轮这些事件,有了就关闭么?
//为什么系统的ToolTip要经过很长延时才被关闭了,再哪儿关闭的?
// bool QApplication::notify(QObject *receiver, QEvent*e)内
    case QEvent::MouseMove: 内
if (e->type() == QEvent::MouseMove && mouse->buttons() == 0)
{
    d->toolTipWidget = w;
    d->toolTipPos =relpos;
    d->toolTipGlobalPos =mouse->globalPos();
    d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive()?20:700, this);
}
//如果在过程中出现下列事件,则使睡眠定时器
// User input and windowactivation makes tooltips sleep
switch (e->type()) {
    caseQEvent::Wheel:
    case QEvent::ActivationChange:
    case QEvent::KeyPress:
    case QEvent::KeyRelease:
    case QEvent::FocusOut:
    case QEvent::FocusIn:
    case QEvent::MouseButtonPress:
    case QEvent::MouseButtonRelease:
    case QEvent::MouseButtonDblClick:
        d->toolTipFallAsleep.stop();
        // fall-through
    case QEvent::Leave:
        d->toolTipWakeUp.stop();
    default:
        break;
}
  QEvent::ToolTip的发送:sendEvent()tooltip事件是由上面提到的定时器触发的。
并在 
QApplication::Event 函数中通过
响应对应的定时器来发送到指定的窗口中。 
        if (te->timerId() == d->toolTipWakeUp.timerId()){
            d->toolTipWakeUp.stop();// 先停止WakeUp定时器
            if (d->toolTipWidget) {
                QWidget *w = d->toolTipWidget->window();
                //show tooltip if WA_AlwaysShowToolTips is set, orif
                // any ancestor ofd->toolTipWidget is the active
                // window
                bool showToolTip = w->testAttribute(Qt::WA_AlwaysShowToolTips);// 判断该属性,如果有就直接跳过下面的while了.
                while (w && !showToolTip) {// 判断是否有容纳ToolTip的控件
                    showToolTip = w->isActiveWindow(); //如果没被激活
                    w = w->parentWidget();             //指向父窗口
                    w = w ? w->window() : 0;           //父窗口不是顶级窗口
                }
                if (showToolTip) { // 如果有
                    QHelpEvent e(QEvent::ToolTip, d->toolTipPos, d->toolTipGlobalPos); // 则生成ToolTip事件
                    QApplication::sendEvent(d->toolTipWidget, &e); // 发送之
                    if (e.isAccepted()) // 如果被某一个Widget接受了
                        d->toolTipFallAsleep.start(2000, this); // 以2000ms启动FallAsleep计时器
                }
            }
        }else if(te->timerId() == d->toolTipFallAsleep.timerId()) {
            d->toolTipFallAsleep.stop();
        }
 QWidget对 QEvent::ToolTip的响应好吧,tool tip的事件已经知道是怎么发送到指定的QWidget了,
现在就看看QWiget是怎么处理ToolTip事件的, 
QWidget::Event()的相关代码段如下:
case QEvent::ToolTip:
        if (!d->toolTip.isEmpty())
            QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(),d->toolTip, this);
        else
            event->ignore();
        break;
至于QToolTip自身又是怎么显示的,就不详细记述了。其实,就是显示一个
QLabel打完收工~  
以下是自己实现的. 
#include "tooltips1.h"
#include<QPushButton>
#include <QBasicTimer>
#include <QToolTip>
tooltips1::tooltips1(QWidget *parent,Qt::WFlags flags)
: QWidget(parent, flags)
{
    ui.setupUi(this);
    setToolTip("hello");
    QPushButton *btn = new QPushButton("hello",this);
    btn->show();
}
tooltips1::~tooltips1()
{
}
bool tooltips1::event(QEvent *e)
{
    if(e->type() == QEvent::ToolTip)
    {
        //头文件声明QBasicTimer timer;
        timer->start(500,this);
    //QToolTip::showText(static_cast<QHelpEvent*>(e)->globalPos(),"hello");
    }
    else if (e->type() == QEvent::Timer)
    {
        QTimerEvent *timerevent = static_cast<QTimerEvent*>(e);
        if(timerevent->timerId()== timer->timerId())
        {
            QToolTip::hideText();
            timer->stop();
        }
    }
    return QWidget::event(e);
}
 现在对于这个过程还有一个疑问,就是它是如何定时消失掉的呢?