在Qt5中接收多个弹出式小部件的鼠标进入和离开事件

4
从Qt 4.8升级到5.4后,我遇到了以下问题... 当我使用设置了Qt::Popup标志的多个小部件时,只有第一个小部件能接收鼠标的enterEventleaveEvent事件。
在4.8.0版本中,所有弹出式小部件都会对鼠标进入或离开做出反应。
这是Qt5的正常行为还是某个错误?
使用下面的代码,只有第一个弹出式小部件w1会报告关于鼠标移动的enterEventleaveEvent。如果没有设置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();
}
1个回答

2

有同样的问题。在Qt5中,如果您同时使用多个弹出窗口,则无法使用标准按钮悬停效果,即使在弹出窗口内部打开弹出窗口也是如此。我开始使用Qt :: Tool而不是Qt :: Popup来避免这个问题。

在窗口构造函数中(我使用QFrame作为基类):

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

打开窗口:

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

处理失去焦点事件:

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

全局事件过滤器,用于捕获由滚轮引起的失去焦点事件(将其安装在您的主窗口上):

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);
}

我用了类似这样的东西,它起作用了,但是后来我遇到了一个奇怪的 bug,在 Windows 10 上,当你:
  • 显示小部件
  • 隐藏它
  • 进入平板电脑模式
  • 返回正常模式
  • 小部件再次显示(但不会收到 showEvent() 或任何事件)。
我正在尝试找出一种仍然可以使用 Qt::Popup 在其他小部件上获取事件的方法,看起来我需要使用自己的鼠标低级钩子来知道鼠标何时悬停在小部件上...虽然这似乎有点过度kill。
- MGamsby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接