qt模拟鼠标左击下移动

如果你只需要模拟鼠标点击效果而不需要模拟在按下鼠标左键的同时移动鼠标效果就不需要导入User32.Lib

 

模拟鼠标点击效果:

QPoint pos;
pos.setX(88);
pos.setY(58);
QMouseEvent *mEvnPress;
QMouseEvent *mEvnRelease;
mEvnPress = new QMouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QApplication::sendEvent(QWidget::focusWidget(),mEvnPress);  //
mEvnRelease = new QMouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QApplication::sendEvent(QWidget::focusWidget(),mEvnRelease);  

函数原型:

QMouseEvent(Type type, const QPointF &localPos, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)

说明:
这里的pos的位置是接受鼠标事件的widget的内部的一个局部位置。也就是说他的鼠标按键的产生点是:先通过
QApplication::sendEvent(QWidget::focusWidget(),mEvnPress);//也就是说先是指明了传递给哪个widget
然后再根据mEventPress来进行具体的再改widget中的定位,以及具体的按键是什么。

下图是第一个参数Type的一些值:

(这个MouseMove就是鼠标左键按下时移动?,但是我用的时候不符合我的要求,好像不是我要的那种左键按下时移动的效果,你们可以试一试)

bool MainWidget::eventFilter(QObject *target, QEvent *event)
{
    if(event->type()==QEvent::FocusIn){//event->type()==QEvent::Enter ||
        static_cast<QPushButton*>(target)->setStyleSheet("background-color: rgb(129, 129,129)");
        QPalette pal;
        pal.setColor(QPalette::Active,QPalette::ButtonText,Qt::red);        
        static_cast<QPushButton*>(target)->setPalette(pal);
    }
    else if(event->type()==QEvent::FocusOut){//event->type()==QEvent::Leave ||
        static_cast<QPushButton*>(target)->setStyleSheet("");
        QPalette pal;
        pal.setColor(QPalette::Active,QPalette::ButtonText,Qt::black);
        static_cast<QPushButton*>(target)->setPalette(pal);
    }
    else if(event->type()== QEvent::KeyPress){
        QPoint pos;
        QWidget *now_button= QWidget::focusWidget();
        QKeyEvent *k = (QKeyEvent *)event;
        QLayoutItem *next_button;
        switch (k->key()){

        case Qt::Key_Up:
            next_button= ui->gridLayout->itemAt((ui->gridLayout->indexOf(now_button)+8)%12);
            next_button->widget()->setFocus();
            break;
        case Qt::Key_Down:
            next_button= ui->gridLayout->itemAt((ui->gridLayout->indexOf(now_button)+4)%12);
            next_button->widget()->setFocus();
#ifdef COURSE
            QCursor::setPos(pos);
#endif
            break;
        case Qt::Key_Left:
            next_button= ui->gridLayout->itemAt((ui->gridLayout->indexOf(now_button)-1+12)%12);
            next_button->widget()->setFocus();
#ifdef COURSE
            QCursor::setPos(pos);
#endif
            break;
        case Qt::Key_Right:
            next_button= ui->gridLayout->itemAt((ui->gridLayout->indexOf(now_button)+1)%12);
            next_button->widget()->setFocus();
            break;
        case Qt::Key_Period:
            pos = now_button->pos();
            pos.setX( 20 + pos.x()+(now_button->width())/2 );
            pos.setY( 20 + pos.y()+(now_button->height())/2 );
            //printf("/n***%d1 %d***/n",pos.x(),pos.y());
#ifdef COURSE
            QCursor::setPos(pos);
#endif
            pos.setX(88);
            pos.setY(58);
            QMouseEvent *mEvnPress;
            QMouseEvent *mEvnRelease;
            mEvnPress = new QMouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
            QApplication::sendEvent(QWidget::focusWidget(),mEvnPress);
            mEvnRelease = new QMouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
            QApplication::sendEvent(QWidget::focusWidget(),mEvnRelease);
            next_button = ui->gridLayout->itemAt(ui->gridLayout->indexOf(QWidget::focusWidget()));
            break;
        default:
            return QWidget::eventFilter(target,event);
        }

        if(next_button){
            pos.setX( 20 + next_button->geometry().x() + (next_button->geometry().width()) / 2 );
            pos.setY( 20 + next_button->geometry().y() + (next_button->geometry().height()) / 2);
#ifdef COURSE
            QCursor::setPos(pos);
#endif
        }
        return true;
    }
    return QWidget::eventFilter(target,event);
}

 

模拟鼠标左击下移动(我写了一个实例,可以看我另外一篇博客: Qt实现鼠标拖拉窗口,并实现模拟鼠标拖拉窗口代码实例):

使用到了mouse_event函数,这个函数我们主要使用下面几种类型参数:

mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);//原位置左键按下
            //Sleep(33);
mouse_event(MOUSEEVENTF_MOVE,0,300,0,0);//向下移动300
            //Sleep(33);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);//在移动后的位置释放左键
//函数原型
VOID mouse_event(  
    DWORD dwFlags, // motion and click options  
    DWORD dx, // horizontal position or change  
    DWORD dy, // vertical position or change  
    DWORD dwData, // wheel movement  
    ULONG_PTR dwExtraInfo // application-defined information  
);  

/*函数参数介绍


dwFlags:标志位集,指定点击按钮和鼠标动作的多种情况。
dx:指定鼠标沿x轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOUSEEVENTF_ABSOLUTE的设置。给出的绝对数据作为鼠标的实际X坐标;给出的相对数据作为移动的mickeys数。一个mickey表示鼠标移动的数量,表明鼠标已经移动。
dy:指定鼠标沿y轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOUSEEVENTF_ABSOLUTE的设置。给出的绝对数据作为鼠标的实际y坐标,给出的相对数据作为移动的mickeys数。
dwData:如果dwFlags为MOUSEEVENTF_WHEEL,则dwData指定鼠标轮移动的数量。正值表明鼠标轮向前转动,即远离用户的方向;负值表明鼠标轮向后转动,即朝向用户。一个轮击定义为WHEEL_DELTA,即120。如果dwFlagsS不是MOUSEEVENTF_WHEEL,则dWData应为零。
dwExtralnfo:指定与鼠标事件相关的附加32位值。应用程序调用函数GetMessageExtraInfo来获得此附加信息。


*/

常用键值表:

 

键盘键与虚拟键码对照表  

字母和数字键     数字小键盘的键   功能键         其它键   
键   键码    键   键码   键    键码   键          键码   
A   65     0    96    F1    112   Backspace    8   
B   66     1    97    F2    113   Tab        9   
C   67     2    98     F3    114   Clear      12   
D   68     3    99    F4    115   Enter      13   
E   69     4    100   F5    116   Shift      16   
F   70     5    101   F6    117   Control     17   
G   71     6    102   F7    118   Alt        18   
H   72     7    103   F8    119   Caps Lock    20   
I   73     8    104   F9    120   Esc        27   
J   74     9    105   F10   121   Spacebar    32   
K   75     *    106   F11   122   Page Up     33   
L   76     +    107   F12   123   Page Down    34   
M   77     Enter 108   --     --   End        35   
N   78     -    109   --     --   Home       36   
O   79     .    110   --     --   Left Arrow   37   
P   80     /    111   --     --   Up Arrow     38   
Q   81    --    --   --     --    Right Arrow   39   
R   82    --    --   --     --   Down Arrow    40   
S   83    --    --   --     --   Insert       45   
T   84    --    --   --     --   Delete       46   
U   85    --    --   --     --   Help        47   
V   86    --    --   --     --   Num Lock     144   
W   87            
X   88        
Y   89        
Z   90        
0   48        
1   49        
2   50         
3   51         
4   52         
5   53         
6   54         
7   55         
8   56         
9   57    

 

 

 

需要导入头文件:

//注意导入这两个头文件顺序不能错
#include "Windows.h"
#include "WinUser.h"

如果报错出现“报错C1189 #error: "No Target Architecture"”那就是头文件导入出现了问题(更多解决办法看:https://www.cnblogs.com/kevinWu7/p/10163436.html

"No Target Architecture"原因:

是因为单独包含了一些windows.h已经包含了的头文件如"fileapi.h","WinUser.h",但是却没有包含windows.h
或者
先包含了如"fileapi.h","WinUser.h",后包含windows.h,顺序不对

先说解决方案:

在代码中 加入include  “windows.h” 即可,或者调整顺序,把winows.h放在前面

 

然后导入User32.Lib这个库,这个库你可以在你的C盘搜索这个文件(我是这样找到的)

然后导入到Qt的pro文件中就行了(导入vs中的方法自行百度吧,好多人讲)

LIBS += F:\Qt\workspace\MouseTest\lib\User32.Lib

 

也可以配置相对路径(对Qt Creator),是相对pro文件的,但是要注意在pro文件内的有些相对路径不是相对于pro文件

原文见:https://blog.csdn.net/u010846653/article/details/73466872

1.相对于pro文件本身的相对路径,例如:

INCLUDEPATH += \
            ../AAA\
            ../BBB \
            ../CCC \
            ../DDD \
//还有source ,form,headers 的文件亦如此。

 

2.相对于构建生成目录的相对路径。

win32:CONFIG(debug) {
    DESTDIR = ../output/debug/bin
    OBJECTS_DIR = ./debug/obj
    MOC_DIR = ./debug/moc
 
    LIBS += -L../output/debug/lib/ \
            -laaa \
            -lbbb \
            -lccc \
            -lddd \
}
 
win32:CONFIG(release) {
    DESTDIR = ../output/release/bin
    OBJECTS_DIR = ./release/obj
    MOC_DIR = ./release/moc
 
    LIBS += -L../output/release/lib/ \
            -laaa \
            -lbbb \
            -lccc \
            -lddd \
}

这里面的相对路径都是基于你项目下的构建目录来的,如下图

 

 

 

 

posted @ 2021-08-04 10:47  kongbursi  阅读(1303)  评论(0编辑  收藏  举报