C++ Qt获取应用程序窗口之外的鼠标事件

C++ Qt获取应用程序窗口之外的鼠标事件,c++,qt,mouseevent,x11,C++,Qt,Mouseevent,X11,首先,我不确定在没有对X.11输入进行某种黑客攻击的情况下这是否可能,但我看到的情况让我认为这是可能的 请允许我解释一下我希望做什么。我想要一个Qt应用程序,它很可能只是一个小窗口,在屏幕上有点像一个小部件。在用户将另一个应用程序窗口拖动到应用程序顶部之前,应用程序不会执行任何操作。我希望检测到这一点的方法是跟踪鼠标,看看鼠标是否按下,鼠标是否在Qt窗口上,Qt是否不是活动窗口,然后执行一些操作。然而,当我的Qt应用程序不是活动窗口时,我目前还无法获取鼠标事件。我想我链接的这些帖子中有一些把“窗

首先,我不确定在没有对X.11输入进行某种黑客攻击的情况下这是否可能,但我看到的情况让我认为这是可能的

请允许我解释一下我希望做什么。我想要一个Qt应用程序,它很可能只是一个小窗口,在屏幕上有点像一个小部件。在用户将另一个应用程序窗口拖动到应用程序顶部之前,应用程序不会执行任何操作。我希望检测到这一点的方法是跟踪鼠标,看看鼠标是否按下,鼠标是否在Qt窗口上,Qt是否不是活动窗口,然后执行一些操作。然而,当我的Qt应用程序不是活动窗口时,我目前还无法获取鼠标事件。我想我链接的这些帖子中有一些把“窗口”称为QApp中的QWindow

然而,我所说的窗口是一个X.11窗口,任何在X中打开的应用程序。我希望我的截图能突出我目前的困境。我也附上了我的代码,很乐意接受任何建议。任何其他已知的帮助我实现这一目标的黑客,我也希望得到通知

红色显示光标单击的位置,鼠标事件记录在Qt窗口之外。然而,这是由“FocusOut”事件触发的,也是我最后一次检测到的事件

正如我们在控制台中看到的,鼠标移动了,但没有捕获任何事件。我真的很想检测鼠标何时越过Qt应用程序窗口所在的位置,而不管它是否位于另一个窗口的顶部

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
    {
      if (event->type() == QEvent::MouseMove)
      {
    QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
    statusBar()->showMessage(QString("Mouse move (%1,%2)").arg(mouseEvent->pos().x()).arg(mouseEvent->pos().y()));
    qDebug() << QString::number(mouseEvent->pos().x());
    qDebug() << QString::number(mouseEvent->pos().y());
  }
  if (event->type() == QEvent::FocusOut)
 {
     QFocusEvent *focusEvent = static_cast<QFocusEvent*>(event);
     focusEvent->accept();
     qDebug()<<"event Filter Mouse Move111"<<QCursor::pos();
 }
  return false;
}


void MainWindow::initWindow()
{
    //Makes the window frameless and always on top
    //setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
    //Makes the window transparent
    //setAttribute(Qt::WA_TranslucentBackground);


    //Allows 'mouseMoved' events to be sent, not sure yet if this will be useful, I think we want mouseDragged
    setMouseTracking(true);
    grabMouse();

    //setup this as an event filter for mouse events
    qApp->installEventFilter(this);
}
bool主窗口::事件过滤器(QObject*obj,QEvent*event)
{
如果(事件->类型()==QEvent::MouseMove)
{
QMouseEvent*mouseeEvent=静态_转换(事件);
statusBar()->showMessage(QString(“鼠标移动(%1,%2)”).arg(mouseEvent->pos().x()).arg(mouseEvent->pos().y());
qDebug()位置().x());
qDebug()位置().y();
}
如果(事件->类型()==QEvent::FocusOut)
{
QFocusEvent*focusEvent=静态播放(事件);
focusEvent->accept();

qDebug()好的,下面是我如何解决这个问题的。Qt中的事件系统,我假设的任何应用程序,在窗口未激活时都不会注册事件。但是,进程显然仍在运行,因此当窗口处于活动状态时,您可以访问数据,而当窗口不再处于活动状态时,您可以访问数据

使用定时轮询方法每n秒获取鼠标位置

//Method used to hopefully track the mouse regardless of whether or not it is inside the active window
void MainWindow::pollMouse(unsigned long sec)
{
    //Loop forever
    while ( true )
    {
        QPoint mouseLoc = QCursor::pos();
        qDebug() << "Mouse position global: x,y"  << mouseLoc.x() << mouseLoc.y();

        QThread::sleep(sec);
    }
}
//用于跟踪鼠标的方法,无论鼠标是否在活动窗口内
void主窗口::轮询鼠标(未签名的长秒)
{
//永远循环
while(true)
{
QPoint mouseLoc=QCursor::pos();

qDebug()你可以修改你的事件过滤器,使其默认为任何事件都以事件类型打印的情况吗?ps:当你没有焦点时,不要指望鼠标事件。当然,UmNyobe,我会看看这是怎么回事,我的下一个攻击计划是每秒轮询几次全局鼠标位置。仍然有一些事件被传递。对于instance,当您将窗口A移到窗口B上时,窗口管理器要求B重新绘制,因为B的一部分变为可见\隐藏。您是否尝试使用
绘制
事件?我不确定它在X系统中是如何运行的,但在窗口上,当其他窗口穿过它时,该窗口应接收到
绘制
事件。如果它在X窗口上是相同的,那么您可以检查它ur
paint
事件,如果您处于活动状态或未处于活动状态。这样,您将区分不同的绘制事件。可能只有在主窗口失去焦点时,您才能执行此操作…就像您在维护窗口的线程上执行此操作一样。此睡眠导致冻结