Qt:强制QWebView点击web元素,即使是窗口中不可见的元素

时间:2022-08-27 12:19:56

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?

有什么办法解决这个问题吗?也许有什么办法可以让窗口像10亿×10亿像素一样运行,但看起来还是200×200呢?

3 个解决方案

#1


7  

I think calling el.evaluateJavaScript("click()"); should work. I say should work because in the past I've been using QWebElement::function() with "click" argument with success. This method did not become part of QWebElement API, however. I think authors came to conclusion it was superfluous in presence of QWebElement::evaluateJavaScript().

我认为打电话el.evaluateJavaScript(“点击()”);应该工作。我说应该工作,因为在过去,我一直在使用QWebElement::function(),用“click”参数表示成功。然而,这个方法并没有成为QWebElement API的一部分。我认为作者得出的结论是::evaluateJavaScript()是多余的。

My similar question - How to follow a link in QWebKit? - still without answer :(
I came up with the same workaround like you here - Problem with evaluateJavaScript()

我有一个类似的问题——如何跟随QWebKit中的链接?-仍然没有答案:(我想到了和您这里一样的解决方案—evaluateJavaScript()的问题

#2


7  

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. 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. The same logic is used if you have to scroll left or right too. Just use Y pixels as a horizontal correction value. I've done this in another language and I know it is doable and works fine. :)

大家好,我知道这个问题由来已久,但我想给出一个不同的答案。你说:“…由于元素没有显示在屏幕上,它不能做算术点击它……嗯,“它”不能做数学,但是“你”可以。,)您可以获得要单击的元素的位置,并计算需要向下/向上滚动多少像素(X)才能使其可见。然后你可以用X像素自动滚动页面,使用X值计算元素的当前位置,然后点击那里。如果你也要向左或向右滚动,也会使用同样的逻辑。只用Y像素作为水平校正值。我用另一种语言做过这个实验,我知道这是可行的,而且效果很好。:)

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. 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.

好吧,我的一个项目也要这么做。为了说明我上面的意思,下面是Qt代码。我意识到它有一些缺陷,特别是当你处理页面边缘的小元素时,但在大多数情况下它是正常的。

(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. I hope it will be useful to someone else too.

当java单击失败时,这就是我的工作。我希望它对别人也有用。

#3


1  

For those who want to click on Webview button then do these

对于那些想要点击Webview按钮的用户,请执行以下操作

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

#1


7  

I think calling el.evaluateJavaScript("click()"); should work. I say should work because in the past I've been using QWebElement::function() with "click" argument with success. This method did not become part of QWebElement API, however. I think authors came to conclusion it was superfluous in presence of QWebElement::evaluateJavaScript().

我认为打电话el.evaluateJavaScript(“点击()”);应该工作。我说应该工作,因为在过去,我一直在使用QWebElement::function(),用“click”参数表示成功。然而,这个方法并没有成为QWebElement API的一部分。我认为作者得出的结论是::evaluateJavaScript()是多余的。

My similar question - How to follow a link in QWebKit? - still without answer :(
I came up with the same workaround like you here - Problem with evaluateJavaScript()

我有一个类似的问题——如何跟随QWebKit中的链接?-仍然没有答案:(我想到了和您这里一样的解决方案—evaluateJavaScript()的问题

#2


7  

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. 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. The same logic is used if you have to scroll left or right too. Just use Y pixels as a horizontal correction value. I've done this in another language and I know it is doable and works fine. :)

大家好,我知道这个问题由来已久,但我想给出一个不同的答案。你说:“…由于元素没有显示在屏幕上,它不能做算术点击它……嗯,“它”不能做数学,但是“你”可以。,)您可以获得要单击的元素的位置,并计算需要向下/向上滚动多少像素(X)才能使其可见。然后你可以用X像素自动滚动页面,使用X值计算元素的当前位置,然后点击那里。如果你也要向左或向右滚动,也会使用同样的逻辑。只用Y像素作为水平校正值。我用另一种语言做过这个实验,我知道这是可行的,而且效果很好。:)

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. 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.

好吧,我的一个项目也要这么做。为了说明我上面的意思,下面是Qt代码。我意识到它有一些缺陷,特别是当你处理页面边缘的小元素时,但在大多数情况下它是正常的。

(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. I hope it will be useful to someone else too.

当java单击失败时,这就是我的工作。我希望它对别人也有用。

#3


1  

For those who want to click on Webview button then do these

对于那些想要点击Webview按钮的用户,请执行以下操作

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