From c4773bc5774c1644c34c1340be2997724f29e27d Mon Sep 17 00:00:00 2001 From: tianduanrui <2407223896@qq.com> Date: Tue, 24 Sep 2019 15:09:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=85=E4=BB=85=E5=9C=A8=E9=BC=A0=E6=A0=87?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E6=97=B6=E6=8D=95=E8=8E=B7=E9=BC=A0=E6=A0=87?= =?UTF-8?q?=20mac=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/exquisite/qqtbodymouselocker.cpp | 51 +++++++++--- src/exquisite/qqtbodymouselocker.h | 7 +- src/exquisite/qqtbodymouselocker_p.cpp | 107 ++++++++++--------------- src/exquisite/qqtbodymouselocker_p.h | 37 ++++++--- test/testmouselocker11/mainwindow.cpp | 4 +- 5 files changed, 114 insertions(+), 92 deletions(-) diff --git a/src/exquisite/qqtbodymouselocker.cpp b/src/exquisite/qqtbodymouselocker.cpp index 5a0e4281..3d01adc8 100644 --- a/src/exquisite/qqtbodymouselocker.cpp +++ b/src/exquisite/qqtbodymouselocker.cpp @@ -27,14 +27,15 @@ void QQtBodyMouseLocker::stopCapture() void QQtBodyMouseLocker::addWindow ( QWidget* target ) { + Q_ASSERT ( target ); Q_D ( QQtBodyMouseLocker ) ; d->addWindow ( target ); } void QQtBodyMouseLocker::removeWindow ( QWidget* target ) { - Q_D ( QQtBodyMouseLocker ) ; - d->removeWindow ( target ); + Q_ASSERT ( target ); + target->removeEventFilter ( this ); } bool QQtBodyMouseLocker::eventFilter ( QObject* watched, QEvent* event ) @@ -53,8 +54,24 @@ bool QQtBodyMouseLocker::eventFilter ( QObject* watched, QEvent* event ) //if ( atti ) // return QObject::eventFilter ( watched, event ); - //static int i = 0; - //pline() << i++ << event->type() << watched->objectName(); + static int i = 0; + pline() << i++ << event->type() << watched->objectName(); + + QWidget* target = qobject_cast ( watched ); + QWidget& w = *target; + + QPoint p0, p1; + p0 = w.rect().topLeft(); + p1 = w.rect().bottomRight(); + p0 = w.mapToGlobal ( p0 ); + p1 = w.mapToGlobal ( p1 ); + QRect r0 = QRect ( p0, p1 ); + + qreal ratio = 1; w.devicePixelRatioF(); + QRect qr0 = QRect ( QPoint ( r0.left() * ratio, r0.top() * ratio ), + QPoint ( r0.right() * ratio, r0.bottom() * ratio ) ); + + QRect globalRect = qr0; Q_D ( QQtBodyMouseLocker ) ; @@ -139,17 +156,17 @@ bool QQtBodyMouseLocker::eventFilter ( QObject* watched, QEvent* event ) return false; } #endif -#if 1 - //用于解决mousetracking时获取鼠标 - //这一个还是有用的,用户设置了多个窗口锁定鼠标的时候,有这个才能实时响应鼠标划过动作进行捕获。在tracking为true的时候。 - //这个在点击之后,其实有一个鼠标的闪烁,加了press?activate?以后就没有了。原因是Thread在运行着,这个导致target改变,thread太快了,target没来得及改变,鼠标光标就被thread移动过去了,可是没有锁定,因为这里面setTargetWidget才是决定锁定的函数。 - case QEvent::MouseMove: + case QEvent::MouseButtonRelease: { - QMouseEvent* e = ( QMouseEvent* ) event; - d->mouseMoveEvent ( e, qobject_cast ( watched ) ); + addWindow ( target ); + return false; + } + case QEvent::WindowDeactivate: + { + //如果不是活动窗口,就失效。----很重要。 + d->addRect ( QRect ( 0, 0, 0, 0 ) ); return false; } -#endif default: break; } @@ -159,3 +176,13 @@ bool QQtBodyMouseLocker::eventFilter ( QObject* watched, QEvent* event ) return QObject::eventFilter ( watched, event ); } + +void QQtClipCursor ( const QRect globalRect ) +{ + QQtBodyMouseMouseLockerThreadHelper::instance()->setTargetGlobalRect ( globalRect ); +} + +QRect QQtGetClipCursor() +{ + return QQtBodyMouseMouseLockerThreadHelper::instance()->getTargetGlobalRect(); +} diff --git a/src/exquisite/qqtbodymouselocker.h b/src/exquisite/qqtbodymouselocker.h index 0a7b1ad1..8b9e2f88 100644 --- a/src/exquisite/qqtbodymouselocker.h +++ b/src/exquisite/qqtbodymouselocker.h @@ -58,8 +58,9 @@ public: void startCapture(); void stopCapture(); - //这里添加、移除需要锁定的窗口。[和内部的自动过程有很多重复,无所谓了。] + //这里添加需要锁定的窗口。[可以重复添加] 等于installEventFilter void addWindow ( QWidget* target ); + //移除锁定的窗口 void removeWindow ( QWidget* target ); // QObject interface @@ -71,4 +72,8 @@ private: Q_DECLARE_PRIVATE ( QQtBodyMouseLocker ) }; +//如果用户感兴趣 +QQTSHARED_EXPORT void QQtClipCursor ( const QRect globalRect ); +QQTSHARED_EXPORT QRect QQtGetClipCursor ( ); + #endif // QQTBODYMOUSELOCKER_H diff --git a/src/exquisite/qqtbodymouselocker_p.cpp b/src/exquisite/qqtbodymouselocker_p.cpp index 94a063a7..30666b4b 100644 --- a/src/exquisite/qqtbodymouselocker_p.cpp +++ b/src/exquisite/qqtbodymouselocker_p.cpp @@ -6,20 +6,27 @@ QQtBodyMouseMouseLockerThreadHelper::QQtBodyMouseMouseLockerThreadHelper ( QObject* parent ) : QThread ( parent ) { workflag = false; - target = 0; + mGlobalRect = QRect ( 0, 0, 0, 0 ); + startCapture(); } QQtBodyMouseMouseLockerThreadHelper::~QQtBodyMouseMouseLockerThreadHelper() { + stopCapture(); } -void QQtBodyMouseMouseLockerThreadHelper::setTargetWidget ( QWidget* target ) +void QQtBodyMouseMouseLockerThreadHelper::setTargetGlobalRect ( QRect globalRect ) { tex.lock(); - this->target = target; + mGlobalRect = globalRect; tex.unlock(); } +QRect QQtBodyMouseMouseLockerThreadHelper::getTargetGlobalRect() +{ + return mGlobalRect; +} + void QQtBodyMouseMouseLockerThreadHelper::startCapture() { tex.lock(); @@ -41,34 +48,23 @@ void QQtBodyMouseMouseLockerThreadHelper::run() { while ( 1 ) { + usleep ( 10 ); + tex.lock(); bool lworkflag = workflag; tex.unlock(); if ( !lworkflag ) return; - QWidget* target; + QRect globalRect; tex.lock(); - target = this->target; + globalRect = this->mGlobalRect; tex.unlock(); - if ( !target ) + if ( globalRect == QRect ( 0, 0, 0, 0 ) ) continue; - //用户必须保证,手动,优先于UI释放本locker。 - if ( !target->isActiveWindow() ) - continue; - - //如果鼠标不在范围内不响应?NO。让用户给标题栏装个eventFilter?press关闭capture,realease开启capture? - - QWidget& w = *target; - - QPoint p0, p1; - p0 = w.rect().topLeft(); - p1 = w.rect().bottomRight(); - p0 = w.mapToGlobal ( p0 ); - p1 = w.mapToGlobal ( p1 ); - QRect s = QRect ( p0, p1 ); + QRect s = globalRect; int x = QCursor::pos().x(); int y = QCursor::pos().y(); @@ -84,21 +80,27 @@ void QQtBodyMouseMouseLockerThreadHelper::run() y1 = s.bottom(); QCursor::setPos ( x1, y1 ); - usleep ( 5 ); } } QQtBodyMouseLockerPrivate::QQtBodyMouseLockerPrivate ( QQtBodyMouseLocker* q ) { q_ptr = q; - helper = new QQtBodyMouseMouseLockerThreadHelper ( q ); - helper->startCapture(); + helper = QQtBodyMouseMouseLockerThreadHelper::instance ( q ); } QQtBodyMouseLockerPrivate::~QQtBodyMouseLockerPrivate() { - helper->stopCapture(); - delete helper; +} + +void QQtBodyMouseLockerPrivate::addRect ( const QRect globalRect ) +{ + helper->setTargetGlobalRect ( globalRect ); +} + +QRect QQtBodyMouseLockerPrivate::getRect() +{ + return helper->getTargetGlobalRect(); } void QQtBodyMouseLockerPrivate::startCapture() @@ -115,43 +117,20 @@ void QQtBodyMouseLockerPrivate::addWindow ( QWidget* target ) { Q_ASSERT ( target ); - Q_Q ( QQtBodyMouseLocker ); - target->installEventFilter ( qobject_cast ( q ) ); - helper->setTargetWidget ( target ); -} - -void QQtBodyMouseLockerPrivate::removeWindow ( QWidget* target ) -{ - Q_ASSERT ( target ); - - Q_Q ( QQtBodyMouseLocker ); - target->removeEventFilter ( qobject_cast ( q ) ); - helper->setTargetWidget ( target ); -} - -void QQtBodyMouseLockerPrivate::focusInEvent ( QFocusEvent* event, QWidget* target ) -{ -} - -void QQtBodyMouseLockerPrivate::focusOutEvent ( QFocusEvent* event, QWidget* target ) -{ -} - -void QQtBodyMouseLockerPrivate::mouseMoveEvent ( QMouseEvent* event, QWidget* target ) -{ - if ( target == 0 ) - { - event->ignore(); - return; - } - - if ( !target->isActiveWindow() ) - { - event->ignore(); - return; - } - - helper->setTargetWidget ( target ); - event->accept(); - return; + QWidget& w = *target; + + QPoint p0, p1; + p0 = w.rect().topLeft(); + p1 = w.rect().bottomRight(); + p0 = w.mapToGlobal ( p0 ); + p1 = w.mapToGlobal ( p1 ); + + qreal ratio = 1; w.devicePixelRatioF(); + QRect r0 = QRect ( p0, p1 ); + QRect qr0 = QRect ( QPoint ( r0.left() * ratio, r0.top() * ratio ), + QPoint ( r0.right() * ratio, r0.bottom() * ratio ) ); + + QRect rectMustIn = qr0; + + helper->setTargetGlobalRect ( rectMustIn ); } diff --git a/src/exquisite/qqtbodymouselocker_p.h b/src/exquisite/qqtbodymouselocker_p.h index 42715b2d..3010d153 100644 --- a/src/exquisite/qqtbodymouselocker_p.h +++ b/src/exquisite/qqtbodymouselocker_p.h @@ -8,22 +8,33 @@ class QQtBodyMouseMouseLockerThreadHelper : public QThread { Q_OBJECT -public: - QQtBodyMouseMouseLockerThreadHelper ( QObject* parent = 0 ); - virtual ~QQtBodyMouseMouseLockerThreadHelper(); - void setTargetWidget ( QWidget* target ); +public: + //建议初始化 + static QQtBodyMouseMouseLockerThreadHelper* instance ( QObject* parent = 0 ) { + static QQtBodyMouseMouseLockerThreadHelper* helper = 0; + if ( !helper ) + helper = new QQtBodyMouseMouseLockerThreadHelper ( parent ); + return helper; + } + + void setTargetGlobalRect ( QRect globalRect ); + QRect getTargetGlobalRect (); void startCapture(); void stopCapture(); +private: + QQtBodyMouseMouseLockerThreadHelper ( QObject* parent = 0 ); + virtual ~QQtBodyMouseMouseLockerThreadHelper(); + // QThread interface protected: virtual void run() override; private: QMutex tex; - QWidget* target; + QRect mGlobalRect; bool workflag; }; @@ -34,17 +45,17 @@ public: QQtBodyMouseLockerPrivate ( QQtBodyMouseLocker* q ); virtual ~QQtBodyMouseLockerPrivate(); + //允许定义区域 QRect(0,0,0,0)为关闭。 = ClipCursor + void addRect ( const QRect globalRect ); + QRect getRect(); + + //允许按照窗口进行定义 + void addWindow ( QWidget* target ); + + //允许手动开关 void startCapture(); void stopCapture(); - void addWindow ( QWidget* target ); - void removeWindow ( QWidget* target ); - -protected: - virtual void focusInEvent ( QFocusEvent* event, QWidget* target = 0 ); - virtual void focusOutEvent ( QFocusEvent* event, QWidget* target = 0 ); - virtual void mouseMoveEvent ( QMouseEvent* event, QWidget* target = 0 ); - private: QQtBodyMouseLocker* q_ptr; Q_DECLARE_PUBLIC ( QQtBodyMouseLocker ) diff --git a/test/testmouselocker11/mainwindow.cpp b/test/testmouselocker11/mainwindow.cpp index 44125c05..c567457d 100644 --- a/test/testmouselocker11/mainwindow.cpp +++ b/test/testmouselocker11/mainwindow.cpp @@ -32,7 +32,7 @@ MainWindow::MainWindow ( QWidget* parent ) : //可选 //helper->startCapture(); //可选 - ui->widget->setMouseTracking ( true ); + ui->widget->setMouseTracking ( false ); //ui->widget_2->setMouseTracking ( true ); //this->installEventFilter ( this ); @@ -41,7 +41,7 @@ MainWindow::MainWindow ( QWidget* parent ) : MainWindow::~MainWindow() { //以下二选1,必选 - helper->stopCapture(); + //helper->stopCapture(); //无论如何要保证MouseLocker优先于ui被释放。 //delete helper; //这个不行的