【问题标题】:Qt: Force QWebView to click on a web element, even one not visible on the windowQt:强制 QWebView 点击一个 web 元素,即使一个在窗口上不可见
【发布时间】:2013-02-21 19:53:39
【问题描述】:

假设我正在尝试单击 QWebView 中的链接,这就是我所拥有的:

// extending QWebView
void MyWebView::click(const QString &selectorQuery)
{
    QWebElement el = this->page()->mainFrame()->findFirstElement(selectorQuery);
    if (!el)
         return;

    el.setFocus();

    QMouseEvent pressEvent(QMouseEvent::MouseButtonPress, el.geometry().center(), 
                    Qt::MouseButton::LeftButton, Qt::LeftButton, Qt::NoModifier);
    QCoreApplication::sendEvent(this, &pressEvent);

    QMouseEvent releaseEvent(QMouseEvent::MouseButtonRelease, 
                             el.geometry().center(), Qt::MouseButton::LeftButton,
                             Qt::LeftButton, Qt::NoModifier);
    QCoreApplication::sendEvent(this, &releaseEvent);
}

你这样称呼它:

myWebView->click("a[href]");  // will click first link on page
myWebView->click("input[type=submit]"); // submits a form

唯一的问题是:如果该元素在窗口中不可见,则无法单击。我的意思是,如果您必须向下滚动才能看到它,则无法单击它。我想这与几何形状有关,因为该元素没有显示在屏幕上,因此无法正确单击它。

有什么想法可以解决这个问题吗?也许某种方式可以让窗口表现得像 10 亿 x 十亿像素,但看起来仍然是 200x200?

【问题讨论】:

    标签: c++ qt qtwebkit qwebview


    【解决方案1】:

    我认为拨打el.evaluateJavaScript("click()"); 应该可以。我说 应该 工作,因为过去我一直在成功使用 QWebElement::function() 和“click”参数。但是,此方法并未成为 QWebElement API 的一部分。我认为作者得出的结论是,在存在 QWebElement::evaluateJavaScript() 时这是多余的。

    我的类似问题 - How to follow a link in QWebKit? - 仍然没有答案 :(
    我在这里想出了和你一样的解决方法 - Problem with evaluateJavaScript()

    【讨论】:

      【解决方案2】:

      您好,我知道这个问题已经很老了,但我想提供一个不同的答案。 您说:“...由于该元素没有显示在屏幕上,因此无法通过数学计算来单击它...”。好吧,“it”不能算数,但“You”可以。 ;) 您可以获取要单击的元素的位置,并计算需要向下/向上滚动多少像素 (X) 才能使其可见。然后您可以自动滚动页面 X 像素,并使用 X 值计算元素的当前位置并点击那里。如果您也必须向左或向右滚动,则使用相同的逻辑。只需使用 Y 个像素作为水平校正值。 我已经用另一种语言完成了这项工作,我知道这是可行的并且工作正常。 :)

      编辑:(2013 年 2 月 21 日)

      好的,我也必须为我的一个项目这样做。所以为了说明我上面的意思,下面是 Qt 代码。我意识到它有一些缺陷,尤其是在处理页面边缘周围的小元素时,但在大多数情况下它工作得很好。

      (在下面的代码中,*elemt 是您要点击的元素,*web 是 QWebView 小部件)

      QRect elGeom=element->geometry();
      QPoint elPoint=elGeom.center();
      int elX=elPoint.x();
      int elY=elPoint.y();
      int webWidth=web->width();
      int webHeight=web->height();
      int pixelsToScrolRight=0;
      int pixelsToScrolDown=0;
      if (elX>webWidth) pixelsToScrolRight=elX-webWidth+elGeom.width()/2+10; //the +10 part if for the page to scroll a bit further
      if (elY>webHeight) pixelsToScrolDown=elY-webHeight+elGeom.height()/2+10; //the +10 part if for the page to scroll a bit further
      web->page()->mainFrame()->setScrollBarValue(Qt::Horizontal,pixelsToScrolRight);
      web->page()->mainFrame()->setScrollBarValue(Qt::Vertical,pixelsToScrolDown);
      QPoint pointToClick(elX-pixelsToScrolRight,elY-pixelsToScrolDown);
      
      QMouseEvent pressEvent(QMouseEvent::MouseButtonPress,pointToClick,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);
      QCoreApplication::sendEvent(web, &pressEvent);
      QMouseEvent releaseEvent(QMouseEvent::MouseButtonRelease,pointToClick,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);
      QCoreApplication::sendEvent(web, &releaseEvent);
      

      当 java 点击失败时,这对我有用。我希望它对其他人也有用。

      【讨论】:

      • 太棒了!对于在后台运行 QWebPage(因此他们没有 QWebView)的用户,使用 webPage.currentFrame()->documentElement().geometry() 获取 web->width()web->height() 也可以!
      【解决方案3】:

      对于那些想要点击 Webview 按钮的人,请执行这些操作

      frame1->evaluateJavaScript( "document.forms[0].submit();" ); 
      

      【讨论】:

      • 好的答案,可以解释一下吗?
      猜你喜欢
      • 2012-12-02
      • 1970-01-01
      • 2015-12-20
      • 2022-08-22
      • 1970-01-01
      • 1970-01-01
      • 2018-07-27
      • 2011-08-30
      • 2012-09-14
      相关资源
      最近更新 更多