关于python:是否有可能在QWebView上人为触发mousePressEvent?

Is it possible to trigger a mousePressEvent artificially on a QWebView?

由于Pyqt4上有一个天文上的残暴虫,我需要在QWebView上人为地发射一个mousepressevent作为最后的希望。由于一些不清楚的原因,当点击链接涉及到javascript(例如,它不适用于YouTube视频)以及当用鼠标左键点击链接时,QWebView的LinkClicked和UrlChanged信号不会传递一个qurl。当用中键和右键单击链接时,可以完全访问qurl。

1
2
3
4
5
6
7
8
9
10
11
class CQWebView(QtWebKit.QWebView):

    def mousePressEvent(self, event):
        if type(event) == QtGui.QMouseEvent:
            if event.button() == QtCore.Qt.LeftButton:
                # FIRE A QtCore.Qt.MiddleButton EVENT HERE,
                # SO THAT I CAN GET THE BLOODY LINK AFTERWARDS.
            elif event.button() == QtCore.Qt.MiddleButton:
                self.emit(QtCore.SIGNAL("OPEN_IN_NEW_TAB")) # Example
            elif event.button() == QtCore.Qt.RightButton:
                self.emit(QtCore.SIGNAL("XXX")) # Example

所以,我真的想"人工点击",点击而不点击,只需触发点击链接上的右中键的事件,这样我就可以正确地捕捉到这个曲尔。


您也可以使用QtTest模块来完成。在Web视图上设置事件筛选器,并检查鼠标左键单击事件并发送鼠标中键单击

1
2
3
4
5
6
7
8
9
10
11
def __init__(...)
    self.ui_web_view.installEventFilter(self)

def eventFilter(self, obj, event):
    if obj == self.ui_web_view:
        if event.type() == QtCore.QEvent.MouseButtonPress:
            if event.button() == QtCore.Qt.LeftButton:
                print 'Handled'
                QtTest.QTest.mouseClick(self.ui_web_view, QtCore.Qt.MiddleButton, QtCore.Qt.NoModifier, event.pos())
                return True
    return False


我通过使用qtgui.qapplication中的sendEvent方法单击左边的按钮,成功地单击了中间的按钮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class CQWebView(QtWebKit.QWebView):

    app = None

    def __init__(self, app):
        QtWebKit.QWebView.__init__(self)
        CQWebView.app = app

    def mousePressEvent(self, event):
        if type(event) == QtGui.QMouseEvent:
            if event.button() == QtCore.Qt.LeftButton:
                CQWebView.app.sendEvent(self, QtGui.QMouseEvent(event.type(), event.pos(), QtCore.Qt.MiddleButton, event.buttons(), event.modifiers()))
            elif event.button() == QtCore.Qt.MiddleButton:
                self.emit(QtCore.SIGNAL("linkClicked(const QUrl&)")) # Problem
            elif event.button() == QtCore.Qt.RightButton:
                self.emit(QtCore.SIGNAL("XXX")) # Example

我只需要在实例化时将QApplication的实例传递给自定义QWebView的实例:

1
2
def compose_tab(self, index):
        self.tabs[index].append(CQWebView(self))

这样,我用鼠标左键单击QWebView,用鼠标中键手动单击它。问题是这样做的话,我将覆盖来自QWebView的LinkClicked和UrlChanged信号的默认行为。即使我可以发出这些信号,我也无法访问被单击的链接的地址,因为通过访问qwebview.url()只提供了当前的qurl,而不是将来单击的qurl。

真令人沮丧。