简体   繁体   English

在Qt5中的多个弹出窗口小部件上接收鼠标EnterEvent和LeaveEvent

[英]Receiving mouse EnterEvent and LeaveEvent on multiple popup widgets in Qt5

After porting from Qt 4.8 to 5.4 I've got next problem... When I'm showing multiple widgets with Qt::Popup flag set, only the first of them can receive mouse enterEvent or leaveEvent . 从Qt 4.8移植到5.4后我遇到了下一个问题...当我显示多个小部件并设置Qt::Popup标志时,只有第一enterEvent可以接收鼠标enterEventleaveEvent
With 4.8.0 version all of popup widgets reacted on mouse entering or leaving. 使用4.8.0版本时,所有弹出窗口小部件都会在鼠标进入或离开时作出反应。

Is this normal for Qt5 or some bug? 这对Qt5或某些bug来说是正常的吗?

With code below only the first popup widget w1 reporting about enterEvent and leaveEvent on mouse moving. 使用下面的代码,只有第一个弹出窗口小部件w1报告有关鼠标移动时的enterEventleaveEvent If Qt::Popup flag is not set all widgets report. 如果没有设置Qt::Popup标志,则所有小部件都会报告。

class PopupWidget : public QWidget
{
Q_OBJECT
public:
    explicit PopupWidget( QWidget *parent = 0):QWidget(parent)
    {
    setWindowFlags( windowFlags() | Qt::Popup );
    setAutoFillBackground( true );
    setFixedSize( 100, 100 );
    }

protected:
    void    enterEvent(QEvent * event)
    { qDebug() << "enterEvent"; }

    void    leaveEvent(QEvent * event)
    { qDebug() << "leaveEvent"; }
};

void main()
{
    PopupWidget w1, w2, w3;

    w1.move( mapToGlobal(QPoint(0,0)) );
    w1.show();

    w2.move( mapToGlobal(QPoint(110,0)) );
    w2.show();

    w3.move( mapToGlobal(QPoint(220,0)) );
    w3.show();
}

Same problem. 同样的问题。 Seems, in Qt5 you can't use multiple popups at the same time. 似乎在Qt5中你不能同时使用多个弹出窗口。 Even standard hover effects for buttons stop working if you open popup inside popup. 如果在弹出窗口中打开弹出窗口,即使按钮的标准悬停效果也会停止工作。 I started to use Qt::Tool instead of Qt::Popup to avoid this problem. 我开始使用Qt::Tool而不是Qt::Popup来避免这个问题。

In window constructor (I use QFrame as a base class): 在窗口构造函数中(我使用QFrame作为基类):

setWindowFlags (Qt::Tool | Qt::FramelessWindowHint);

Opening window: 开窗口:

QFrame::show();
QApplication::setActiveWindow (this);

Handling focus out events: 处理焦点事件:

bool event (QEvent * e)
{ if(e->type() == QEvent::WindowDeactivate) hide();
  return QFrame::event (e);
}

Global event filter to catch focus out events caused by wheel (install it on your main window): 全局事件过滤器,用于捕获由轮子引起的焦点事件(将其安装在主窗口上):

bool eventFilter (QObject * obj, QEvent * e)
{ if(e->type() == QEvent::Wheel)
  { QWidget * w = qobject_cast <QWidget*> (obj);
    QWidget * aw = QApplication::activeWindow();
    if(w && !w->isActiveWindow() && aw != m_MainWindow) aw->hide();
  }
  return QObject::eventFilter (obj, e);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM