简体   繁体   English

Qt:强制QWebView点击一个web元素,即使是在窗口中看不到的元素

[英]Qt: Force QWebView to click on a web element, even one not visible on the window

So let's say I'm trying to click a link in the QWebView, here is what I have: 所以,假设我试图点击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);
}

And you call it as so: 你这么称呼它:

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

THE ONLY PROBLEM IS: if the element is not visible in the window, it is impossible to click. 唯一的问题是: 如果在窗口中看不到元素,则无法点击。 What I mean is if you have to scroll down to see it, you can't click it. 我的意思是如果你必须向下滚动才能看到它,你不能点击它。 I imagine this has to do with the geometry, since the element doesn't show up on the screen it can't do the math to click it right. 我想这与几何有关,因为元素没有显示在屏幕上,所以无法进行数学计算以单击它。

Any ideas to get around this? 有什么想法来解决这个问题吗? Maybe some way to make the window behave like a billion x billion pixels but still look 200x200? 也许某种方式使窗口表现像十亿十亿像素,但仍然看起来200x200?

Hi I know this question is quite old, but I wanted to offer a different answer. 嗨,我知道这个问题很老,但我想提供一个不同的答案。 You said: "...since the element doesn't show up on the screen it can't do the math to click it...". 你说:“......因为元素没有显示在屏幕上,所以无法点击它...”。 Well, " it " can not do the math, but " You " can. 好吧,“ ”不能做数学,但“ ”可以。 ;) You can get the position of the element you want to click on and calculate how many pixels ( X ) you need to scroll down/up in order to make it visible. ;)您可以获取要单击的元素的位置,并计算向下/向上滚动所需的像素数( X )以使其可见。 Then you can auto scroll the page by X pixels and use the X value to calculate the current position of the element and click there. 然后,您可以按X像素自动滚动页面,并使用X值计算元素的当前位置,然后单击此处。 The same logic is used if you have to scroll left or right too. 如果您还必须向左或向右滚动,则使用相同的逻辑。 Just use Y pixels as a horizontal correction value. 只需使用Y像素作为水平校正值。 I've done this in another language and I know it is doable and works fine. 我用另一种语言做了这个,我知道它是可行的并且工作正常。 :) :)

EDIT: (Feb 21 2013) 编辑:( 2013年2月21日)

OK, I had to do this for one of my projects too. 好的,我也必须为我的一个项目做这个。 So to illustrate what I meant above, below is the Qt code. 为了说明我的意思,下面是Qt代码。 I realize it has some flaws, especially if you are dealing with small elements around the page edges, but in most cases it works just fine. 我意识到它有一些缺陷,特别是如果你处理页面边缘周围的小元素,但在大多数情况下它工作得很好。

(in the code below *elemt is the element you want to click on and *web is the QWebView widget) (在下面的代码中* 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);

This is what works for me, when the java click fails. 当java点击失败时,这对我有用。 I hope it will be useful to someone else too. 我希望它对其他人也有用。

I think calling el.evaluateJavaScript("click()"); 我想调用el.evaluateJavaScript("click()"); should work. 应该管用。 I say should work because in the past I've been using QWebElement::function() with "click" argument with success. 我说应该工作,因为在过去我一直在使用QWebElement::function()和“click”参数成功。 This method did not become part of QWebElement API, however. 但是,此方法未成为QWebElement API的一部分。 I think authors came to conclusion it was superfluous in presence of QWebElement::evaluateJavaScript() . 我认为作者得出的结论是,在QWebElement::evaluateJavaScript()存在下它是多余的。

My similar question - How to follow a link in QWebKit? 我的类似问题 - 如何关注QWebKit中的链接? - still without answer :( - 仍然没有答案:(
I came up with the same workaround like you here - Problem with evaluateJavaScript() 我想出了像你这样的解决方法 - evaluateJavaScript()的问题

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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