Qt:强制 QWebView 单击 Web 元素,即使该元素在窗口上不可见

发布于 2024-08-29 04:29:48 字数 1142 浏览 10 评论 0原文

假设我正在尝试单击 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 10 亿像素,但看起来仍然是 200x200?

So let's say I'm trying to click a link in the QWebView, here is what I have:

// 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

恬淡成诗 2024-09-05 04:29:48

我认为调用 el.evaluateJavaScript("click()"); 应该可以。我说应该可以工作,因为过去我一直成功地使用QWebElement::function()和“click”参数。然而,这个方法并没有成为 QWebElement API 的一部分。我认为作者得出的结论是,在存在 QWebElement::evaluateJavaScript() 的情况下,它是多余的。

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

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

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()

∞琼窗梦回ˉ 2024-09-05 04:29:48

嗨,我知道这个问题很老了,但我想提供一个不同的答案。
您说:“...由于该元素没有显示在屏幕上,因此无法进行数学计算来单击它...”。好吧,“”无法进行数学计算,但“”可以。 ;)
您可以获取要单击的元素的位置,并计算需要向下/向上滚动多少像素 (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 单击失败时,这对我有用。我希望它对其他人也有用。

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

EDIT: (Feb 21 2013)

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.

(in the code below *elemt is the element you want to click on and *web is the QWebView widget)

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.

薄情伤 2024-09-05 04:29:48

对于那些想要单击 Webview 按钮然后执行以下操作的人

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

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

frame1->evaluateJavaScript( "document.forms[0].submit();" ); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文