简体   繁体   中英

simulate mouse drag event PyQt5

I am making a bot that autoClicks a QWebEngineView widget.

I want to simulate a mouseDrag to that widget

ie:-

  • Press left mouse btn on QPoint(100,100)

  • Move the mouse to QPoint(500,500)

  • Release left mouse btn

I tried this code, but it doesn't work:

def drag_from_to(browser_widget, x1, y1, x2, y2):

    for child in browser_widget.findChildren(QtWidgets.QWidget):
        if (child.metaObject().className() == "QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget"):
            #I also tried sending the event to 'browser_widget' instead of 'child'
            event_press = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonPress, QtCore.QPoint(x1, y1),
                                            QtCore.Qt.LeftButton, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier, )
            QtCore.QCoreApplication.postEvent(child, event_press)

            event_move = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, QtCore.QPoint(x2, y2),
                                           QtCore.Qt.LeftButton, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier, )
            QtCore.QCoreApplication.postEvent(child, event_move)

            event_release = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonRelease, QtCore.QPoint(x2, y2),
                                              QtCore.Qt.LeftButton, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier, )
            QtCore.QCoreApplication.postEvent(child, event_release)
            return

EDIT: I also tried QTest.mouseMove()... It actually moves the mouse cursor... but, I want the Bot to run in the background... I want the user to be able to use his computer while the Bot is running

After some tests, I found the solution:-

I have to pause the code execution at least for 1 millisecond after posting a new QEvent.MouseMove, I also have to send that event sequentially to every point on the line between the two points [eg: dragging the mouse from QPoint(x1, y1) to QPoint(x2, y2)]

Here is the working code:

def wait(ms): QTest.qWait(ms) #pauses the code without freezing the UI
def getIntEquidistantPoints(x1, y1, x2, y2):
    n = int(((((x2 - x1 )**2) + ((y2-y1)**2))**0.5))
    def lerp(v0, v1, i): return v0 + i * (v1 - v0)
    return [(int(x), int(y)) for x,y in [(lerp(x1,x2,1./n*i), lerp(y1,y2,1./n*i)) for i in range(n+1)]]
def drag_from_to(browser_widget, x1, y1, x2, y2):
    x1 = int(x1);y1 = int(y1);x2 = int(x2);y2 = int(y2)
    for child in browser_widget.findChildren(QtWidgets.QWidget):
        if (child.metaObject().className() == "QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget"):
            event_press = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonPress, QtCore.QPoint(x1, y1),
                                            QtCore.Qt.LeftButton, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier, )
            QtCore.QCoreApplication.postEvent(child, event_press)
            for p in getIntEquidistantPoints(x1, y1, x2, y2):
                QtCore.QCoreApplication.postEvent(child,
                                                  QMouseEvent(QEvent.MouseMove,
                                                              QtCore.QPoint(p[0], p[1]),
                                                              Qt.NoButton,
                                                              Qt.MouseButtons(Qt.LeftButton),
                                                              Qt.NoModifier)); wait(1)
            event_release = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonRelease, QtCore.QPoint(x2, y2),
                                              QtCore.Qt.LeftButton, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier, )
            QtCore.QCoreApplication.postEvent(child, event_release)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM