以前提过类似的问题,但未解决,现在详细描述一下。
首先这是一个漂浮在桌面下边缘附近、可以拖动的无边框窗口,显示的是一个“LOOK”的卡通形象。LOOK 的眼睛平时是半闭的,隔一段时间会眨眼。当鼠标移动到窗口上时,LOOK 半闭的眼睛会睁大。

这个功能是用 enterEvent 实现的。
- void Look::enterEvent(QEvent*e)
- {
- //
- qDebug() << "enterEvent";
- if (lblSquint->isVisible()) // eyelids visible
- attention(); // open eyes
- //QWidget::enterEvent(e);
- }
一般情况下这个功能正常运行,但是有时 enterEvent 会失效,例如:
右键单击,出现 context menu

不点击退出,而是把鼠标移动到另一个位置,左键单击,把菜单 cancel 掉
之后,enterEvent 就没有反应了,无论怎么移动鼠标,也不会发生 enterEvent。

如果去掉代码里面的 Qt::FramelessWindowHint 就不会发生这个问题,但是卡通形象的效果就没有了。
下面是部分源代码,全部的源文件在压缩包里面。
- #include "look.h"
- #include <QtGui/QAction>
- #include <QtGui/QApplication>
- #include <QtGui/QPixmap>
- #include <QtGui/QLabel>
- #include <QtGui/QMouseEvent>
- #include <QtGui/QDesktopWidget>
- #include <QtCore/QTimer>
- #include <QDebug>
- //Look::Look(QWidget *parent)
- //: QWidget(parent, Qt::FramelessWindowHint | Qt::WindowSystemMenuHint)
- Look::Look()
- {
- setWindowFlags(
- Qt::WindowSystemMenuHint
- | Qt::FramelessWindowHint
- | Qt::WindowStaysOnTopHint
- );
- setAttribute(Qt::WA_TranslucentBackground);
- // load character pic
- imgLook.load(":/image/look.png");
- imgSquint.load(":/image/half.png");
- imgClose.load(":/image/close.png");
- lblLook = new QLabel(this);
- lblLook->setGeometry(imgLook.rect());
- lblLook->setPixmap(imgLook);
- // dock: bottom of availableGeometry (work area?)
- pos_y = QApplication::desktop()->availableGeometry().bottom() - imgLook.height();
- setGeometry(0, pos_y, imgLook.width(), imgLook.height());
- lblClose = new QLabel(this);
- lblClose->setGeometry(62, 38, 69, 56);
- lblClose->setPixmap(imgClose);
- lblClose->hide();
- lblSquint = new QLabel(this);
- lblSquint->setGeometry(62, 38, 69, 30);
- lblSquint->setPixmap(imgSquint);
- lblSquint->show();
- // Wink
- timerWink = new QTimer(this);
- connect(timerWink, SIGNAL(timeout()), this, SLOT(wink()));
- timerWink->start(10000);
- // context Menu
- QAction *quitAction = new QAction(tr("E&xit"), this);
- quitAction->setShortcut(tr("Ctrl+Q"));
- connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
- addAction(quitAction);
- setContextMenuPolicy(Qt::ActionsContextMenu);
- // When screen resolution change
- connect(QApplication::desktop(), SIGNAL(resized(int)),
- this, SLOT(screenResize(int)));
- connect(QApplication::desktop(), SIGNAL(workAreaResized(int)),
- this, SLOT(screenResize(int)));
- }
- void Look::enterEvent(QEvent*e)
- {
- //
- qDebug() << "enterEvent";
- if (lblSquint->isVisible())
- attention();
- //QWidget::enterEvent(e);
- }
- void Look::wink()
- {
- //
- if (lblClose->isHidden())
- lblClose->show();
- QTimer::singleShot(80, this, SLOT(openeyes()));
- }
- void Look::openeyes()
- {
- if (lblClose->isVisible())
- lblClose->hide();
- }
- void Look::screenResize(int screen)
- {
- int temp = QApplication::desktop()->availableGeometry().bottom()
- - imgLook.height();
- // if y is not appropriate
- if (y() != temp) {
- pos_y = temp;
- move(x(), pos_y);
- }
- }
- void Look::mousePressEvent(QMouseEvent*event)
- {
- if (event->button() == Qt::LeftButton) {
- pos_x = event->globalX() - x();
- event->accept();
- }
- else
- event->ignore();
- }
- void Look::mouseMoveEvent(QMouseEvent*event)
- {
- if (event->buttons() & Qt::LeftButton) {
- move(event->globalX() - pos_x, pos_y);
- event->accept();
- }
- }
- void Look::attention()
- {
- lblSquint->hide();
- QTimer::singleShot(6000, this, SLOT(standby()));
- }
- void Look::standby()
- {
- lblSquint->show();
- }
[ 此帖被napier在2009-10-12 11:28重新编辑 ]