1
0
mirror of https://gitee.com/drabel/LibQQt.git synced 2025-01-04 10:18:44 +08:00

仅仅在鼠标点击时捕获鼠标 mac下

This commit is contained in:
tianduanrui 2019-09-24 15:09:52 +08:00
parent bd704c0bad
commit c4773bc577
5 changed files with 114 additions and 92 deletions

View File

@ -27,14 +27,15 @@ void QQtBodyMouseLocker::stopCapture()
void QQtBodyMouseLocker::addWindow ( QWidget* target ) void QQtBodyMouseLocker::addWindow ( QWidget* target )
{ {
Q_ASSERT ( target );
Q_D ( QQtBodyMouseLocker ) ; Q_D ( QQtBodyMouseLocker ) ;
d->addWindow ( target ); d->addWindow ( target );
} }
void QQtBodyMouseLocker::removeWindow ( QWidget* target ) void QQtBodyMouseLocker::removeWindow ( QWidget* target )
{ {
Q_D ( QQtBodyMouseLocker ) ; Q_ASSERT ( target );
d->removeWindow ( target ); target->removeEventFilter ( this );
} }
bool QQtBodyMouseLocker::eventFilter ( QObject* watched, QEvent* event ) bool QQtBodyMouseLocker::eventFilter ( QObject* watched, QEvent* event )
@ -53,8 +54,24 @@ bool QQtBodyMouseLocker::eventFilter ( QObject* watched, QEvent* event )
//if ( atti ) //if ( atti )
// return QObject::eventFilter ( watched, event ); // return QObject::eventFilter ( watched, event );
//static int i = 0; static int i = 0;
//pline() << i++ << event->type() << watched->objectName(); pline() << i++ << event->type() << watched->objectName();
QWidget* target = qobject_cast<QWidget*> ( 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 ) ; Q_D ( QQtBodyMouseLocker ) ;
@ -139,17 +156,17 @@ bool QQtBodyMouseLocker::eventFilter ( QObject* watched, QEvent* event )
return false; return false;
} }
#endif #endif
#if 1 case QEvent::MouseButtonRelease:
//用于解决mousetracking时获取鼠标
//这一个还是有用的用户设置了多个窗口锁定鼠标的时候有这个才能实时响应鼠标划过动作进行捕获。在tracking为true的时候。
//这个在点击之后其实有一个鼠标的闪烁加了pressactivate?以后就没有了。原因是Thread在运行着这个导致target改变thread太快了target没来得及改变鼠标光标就被thread移动过去了可是没有锁定因为这里面setTargetWidget才是决定锁定的函数。
case QEvent::MouseMove:
{ {
QMouseEvent* e = ( QMouseEvent* ) event; addWindow ( target );
d->mouseMoveEvent ( e, qobject_cast<QWidget*> ( watched ) ); return false;
}
case QEvent::WindowDeactivate:
{
//如果不是活动窗口,就失效。----很重要。
d->addRect ( QRect ( 0, 0, 0, 0 ) );
return false; return false;
} }
#endif
default: default:
break; break;
} }
@ -159,3 +176,13 @@ bool QQtBodyMouseLocker::eventFilter ( QObject* watched, QEvent* event )
return QObject::eventFilter ( watched, event ); return QObject::eventFilter ( watched, event );
} }
void QQtClipCursor ( const QRect globalRect )
{
QQtBodyMouseMouseLockerThreadHelper::instance()->setTargetGlobalRect ( globalRect );
}
QRect QQtGetClipCursor()
{
return QQtBodyMouseMouseLockerThreadHelper::instance()->getTargetGlobalRect();
}

View File

@ -58,8 +58,9 @@ public:
void startCapture(); void startCapture();
void stopCapture(); void stopCapture();
//这里添加、移除需要锁定的窗口。[和内部的自动过程有很多重复,无所谓了。] //这里添加需要锁定的窗口。[可以重复添加] 等于installEventFilter
void addWindow ( QWidget* target ); void addWindow ( QWidget* target );
//移除锁定的窗口
void removeWindow ( QWidget* target ); void removeWindow ( QWidget* target );
// QObject interface // QObject interface
@ -71,4 +72,8 @@ private:
Q_DECLARE_PRIVATE ( QQtBodyMouseLocker ) Q_DECLARE_PRIVATE ( QQtBodyMouseLocker )
}; };
//如果用户感兴趣
QQTSHARED_EXPORT void QQtClipCursor ( const QRect globalRect );
QQTSHARED_EXPORT QRect QQtGetClipCursor ( );
#endif // QQTBODYMOUSELOCKER_H #endif // QQTBODYMOUSELOCKER_H

View File

@ -6,20 +6,27 @@
QQtBodyMouseMouseLockerThreadHelper::QQtBodyMouseMouseLockerThreadHelper ( QObject* parent ) : QThread ( parent ) QQtBodyMouseMouseLockerThreadHelper::QQtBodyMouseMouseLockerThreadHelper ( QObject* parent ) : QThread ( parent )
{ {
workflag = false; workflag = false;
target = 0; mGlobalRect = QRect ( 0, 0, 0, 0 );
startCapture();
} }
QQtBodyMouseMouseLockerThreadHelper::~QQtBodyMouseMouseLockerThreadHelper() QQtBodyMouseMouseLockerThreadHelper::~QQtBodyMouseMouseLockerThreadHelper()
{ {
stopCapture();
} }
void QQtBodyMouseMouseLockerThreadHelper::setTargetWidget ( QWidget* target ) void QQtBodyMouseMouseLockerThreadHelper::setTargetGlobalRect ( QRect globalRect )
{ {
tex.lock(); tex.lock();
this->target = target; mGlobalRect = globalRect;
tex.unlock(); tex.unlock();
} }
QRect QQtBodyMouseMouseLockerThreadHelper::getTargetGlobalRect()
{
return mGlobalRect;
}
void QQtBodyMouseMouseLockerThreadHelper::startCapture() void QQtBodyMouseMouseLockerThreadHelper::startCapture()
{ {
tex.lock(); tex.lock();
@ -41,34 +48,23 @@ void QQtBodyMouseMouseLockerThreadHelper::run()
{ {
while ( 1 ) while ( 1 )
{ {
usleep ( 10 );
tex.lock(); tex.lock();
bool lworkflag = workflag; bool lworkflag = workflag;
tex.unlock(); tex.unlock();
if ( !lworkflag ) if ( !lworkflag )
return; return;
QWidget* target; QRect globalRect;
tex.lock(); tex.lock();
target = this->target; globalRect = this->mGlobalRect;
tex.unlock(); tex.unlock();
if ( !target ) if ( globalRect == QRect ( 0, 0, 0, 0 ) )
continue; continue;
//用户必须保证手动优先于UI释放本locker。 QRect s = globalRect;
if ( !target->isActiveWindow() )
continue;
//如果鼠标不在范围内不响应NO。让用户给标题栏装个eventFilterpress关闭capturerealease开启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 );
int x = QCursor::pos().x(); int x = QCursor::pos().x();
int y = QCursor::pos().y(); int y = QCursor::pos().y();
@ -84,21 +80,27 @@ void QQtBodyMouseMouseLockerThreadHelper::run()
y1 = s.bottom(); y1 = s.bottom();
QCursor::setPos ( x1, y1 ); QCursor::setPos ( x1, y1 );
usleep ( 5 );
} }
} }
QQtBodyMouseLockerPrivate::QQtBodyMouseLockerPrivate ( QQtBodyMouseLocker* q ) QQtBodyMouseLockerPrivate::QQtBodyMouseLockerPrivate ( QQtBodyMouseLocker* q )
{ {
q_ptr = q; q_ptr = q;
helper = new QQtBodyMouseMouseLockerThreadHelper ( q ); helper = QQtBodyMouseMouseLockerThreadHelper::instance ( q );
helper->startCapture();
} }
QQtBodyMouseLockerPrivate::~QQtBodyMouseLockerPrivate() QQtBodyMouseLockerPrivate::~QQtBodyMouseLockerPrivate()
{ {
helper->stopCapture(); }
delete helper;
void QQtBodyMouseLockerPrivate::addRect ( const QRect globalRect )
{
helper->setTargetGlobalRect ( globalRect );
}
QRect QQtBodyMouseLockerPrivate::getRect()
{
return helper->getTargetGlobalRect();
} }
void QQtBodyMouseLockerPrivate::startCapture() void QQtBodyMouseLockerPrivate::startCapture()
@ -115,43 +117,20 @@ void QQtBodyMouseLockerPrivate::addWindow ( QWidget* target )
{ {
Q_ASSERT ( target ); Q_ASSERT ( target );
Q_Q ( QQtBodyMouseLocker ); QWidget& w = *target;
target->installEventFilter ( qobject_cast<QObject*> ( q ) );
helper->setTargetWidget ( target ); QPoint p0, p1;
} p0 = w.rect().topLeft();
p1 = w.rect().bottomRight();
void QQtBodyMouseLockerPrivate::removeWindow ( QWidget* target ) p0 = w.mapToGlobal ( p0 );
{ p1 = w.mapToGlobal ( p1 );
Q_ASSERT ( target );
qreal ratio = 1; w.devicePixelRatioF();
Q_Q ( QQtBodyMouseLocker ); QRect r0 = QRect ( p0, p1 );
target->removeEventFilter ( qobject_cast<QObject*> ( q ) ); QRect qr0 = QRect ( QPoint ( r0.left() * ratio, r0.top() * ratio ),
helper->setTargetWidget ( target ); QPoint ( r0.right() * ratio, r0.bottom() * ratio ) );
}
QRect rectMustIn = qr0;
void QQtBodyMouseLockerPrivate::focusInEvent ( QFocusEvent* event, QWidget* target )
{ helper->setTargetGlobalRect ( rectMustIn );
}
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;
} }

View File

@ -8,22 +8,33 @@
class QQtBodyMouseMouseLockerThreadHelper : public QThread class QQtBodyMouseMouseLockerThreadHelper : public QThread
{ {
Q_OBJECT 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 startCapture();
void stopCapture(); void stopCapture();
private:
QQtBodyMouseMouseLockerThreadHelper ( QObject* parent = 0 );
virtual ~QQtBodyMouseMouseLockerThreadHelper();
// QThread interface // QThread interface
protected: protected:
virtual void run() override; virtual void run() override;
private: private:
QMutex tex; QMutex tex;
QWidget* target; QRect mGlobalRect;
bool workflag; bool workflag;
}; };
@ -34,17 +45,17 @@ public:
QQtBodyMouseLockerPrivate ( QQtBodyMouseLocker* q ); QQtBodyMouseLockerPrivate ( QQtBodyMouseLocker* q );
virtual ~QQtBodyMouseLockerPrivate(); virtual ~QQtBodyMouseLockerPrivate();
//允许定义区域 QRect(0,0,0,0)为关闭。 = ClipCursor
void addRect ( const QRect globalRect );
QRect getRect();
//允许按照窗口进行定义
void addWindow ( QWidget* target );
//允许手动开关
void startCapture(); void startCapture();
void stopCapture(); 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: private:
QQtBodyMouseLocker* q_ptr; QQtBodyMouseLocker* q_ptr;
Q_DECLARE_PUBLIC ( QQtBodyMouseLocker ) Q_DECLARE_PUBLIC ( QQtBodyMouseLocker )

View File

@ -32,7 +32,7 @@ MainWindow::MainWindow ( QWidget* parent ) :
//可选 //可选
//helper->startCapture(); //helper->startCapture();
//可选 //可选
ui->widget->setMouseTracking ( true ); ui->widget->setMouseTracking ( false );
//ui->widget_2->setMouseTracking ( true ); //ui->widget_2->setMouseTracking ( true );
//this->installEventFilter ( this ); //this->installEventFilter ( this );
@ -41,7 +41,7 @@ MainWindow::MainWindow ( QWidget* parent ) :
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
//以下二选1必选 //以下二选1必选
helper->stopCapture(); //helper->stopCapture();
//无论如何要保证MouseLocker优先于ui被释放。 //无论如何要保证MouseLocker优先于ui被释放。
//delete helper; //delete helper;
//这个不行的 //这个不行的