gpt4 book ai didi

c++ - 使用按下按钮输入时,QWidget 不会触发 QEvent::MouseMove

转载 作者:太空宇宙 更新时间:2023-11-04 13:36:45 24 4
gpt4 key购买 nike

在带有 C++ 的 Qt 中,我创建了一个窗口,里面有一个小的 QWidget。

每次 QEvent::EnterQEvent::LeaveQEvent::MouseMove 被触发时,小 QWidget 都会显示一条消息。

当在小 QWidget 之外按下(并保持)任何鼠标按钮,并且鼠标移动到这个小 QWidget 的顶部(按住时),QEvent::MouseMove 不会被触发对于这个小 QWidget。此外,QEvent::Enter 被推迟到鼠标按钮释放之后。

在相反的情况下:当鼠标在小 QWidget 上按下(并保持),然后鼠标移到外面时,QEvent::Leave 被推迟到鼠标按钮按下之后发布。

是否有任何解决方案可以始终检索 QEvent::MouseMove,即使在按住鼠标按钮时也是如此?

附加数据:是的,setMouseTracking(true) 已设置。

测试示例:

小部件:

#ifndef MYWIDGET_HPP
#define MYWIDGET_HPP

#include <QWidget>
#include <QStyleOption>
#include <QPainter>
#include <QEvent>
#include <QDebug>

class MyWidget: public QWidget
{
Q_OBJECT
public:
MyWidget( QWidget* parent=nullptr ): QWidget(parent)
{
setMouseTracking(true);
}
protected:

// Paint for styling
void paintEvent(QPaintEvent *)
{
// Needed to allow stylesheet.
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

// Show Enter and Leave event for debugging purpose
bool event( QEvent *e)
{
static int counting=0;
if (e->type() ==QEvent::Enter)
{
qDebug() << counting++ << " Enter: " << this->objectName();
}
if (e->type() ==QEvent::Leave)
{
qDebug() << counting++ << " Leave: " << this->objectName();
}

if (e->type() ==QEvent::MouseMove)
{
qDebug() << counting++ << " Move: " << this->objectName();
}
return QWidget::event(e);
}

};

#endif // MYWIDGET_HPP

主要

#include <QApplication>

#include <QDebug>
#include <QWidget>
#include <QTimer>

#include "Testing.hpp"


int main(int argc, char *argv[])
{
QApplication a(argc, argv);

// Create a main window
QWidget main;
main.setWindowTitle("Cursor blocked for 5s - wait and see");
main.resize(500, 200);
main.move(200, 200);

// Create a MyWidget
MyWidget sub(&main);
sub.setObjectName("sub");
sub.resize(50, 50);
sub.move(50, 50);

// Style the button with a hover
main.setStyleSheet
(
"QWidget#sub{background-color: rgba(0,0,128,0.5);}"
"QWidget#sub:hover{background-color: rgba(128,0,0,0.5);}"
);

// Show the window
main.show();

return a.exec();

}

项目

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

SOURCES +=\
main.cpp

HEADERS +=\
Testing.hpp

RESOURCES +=\

CONFIG += c++11 -Wall

TARGET = Testing
TEMPLATE = app

最佳答案

这是标准行为。当您按下鼠标按钮时,小部件开始抓取它(调用 QWidget::grabMouse)。我认为当您需要全局跟踪鼠标时,您应该重新设计您的行为,或者解释一些真实的用例。

如果你真的需要跟踪鼠标,你可以使用事件过滤器。

伪代码(没有检查):

QWidget *otherWidget = /*...*/;
QWidget *myWidget = /*...*/;
otherWidget->installEventFilter( myWidget );
// you need to install filter on each widget,
// that you want to track.
// Care with performance

MyWidget : QWidget
{
void handleMouseMove( QPoint pos ) { /*...you code...*/ }

void mouseMove( QMouseEvent *e ) override;
{
handleMouseMove( e->pos() );
QWidget::mouseMove( e );
}

bool eventFilter( QObject *obj, QEvent *e )
{
auto srcWidget = qobject_cast< QWidget * >( obj );
switch ( e->type() )
{
case QEvent::MouseMove:
{
auto me = static_cast< QMouseEvent * >( e );
auto globalPos = srcWidget->mapToGlobal( me->pos() );
auto localPos = this->mapFromGlobal( globalPos ); // Possible, you need to invalidate that poing belongs to widget
handleMouseMove( localPos );
}
break;
};
return QWidget::eventFilter( obj, e );
}
};

关于c++ - 使用按下按钮输入时,QWidget 不会触发 QEvent::MouseMove,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29294905/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com