Qt: заставить QWebView щелкнуть веб-элемент, даже если он не виден в окне.

Итак, скажем, я пытаюсь щелкнуть ссылку в 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

ЕДИНСТВЕННАЯ ПРОБЛЕМА: если элемент не виден в окне, по нему невозможно щелкнуть. Я имею в виду, что если вам нужно прокрутить вниз, чтобы увидеть его, вы не сможете щелкнуть по нему. Я предполагаю, что это связано с геометрией, поскольку элемент не отображается на экране, он не может посчитать, чтобы щелкнуть его правильно.

Любые идеи, чтобы обойти это? Может быть, какой-то способ заставить окно вести себя как миллиард х миллиардов пикселей, но при этом выглядеть 200x200?


person Pirate for Profit    schedule 16.04.2010    source источник


Ответы (3)


Я думаю, вызов el.evaluateJavaScript("click()"); должен сработать. Я говорю, что должен работать, потому что в прошлом я успешно использовал QWebElement::function() с аргументом "щелчок". Однако этот метод не стал частью QWebElement API. Думаю, авторы пришли к выводу, что присутствие QWebElement::evaluateJavaScript() было излишним.

Мой аналогичный вопрос - Как перейти по ссылке в QWebKit? - все еще без ответа :(
Я нашел тот же обходной путь, что и вы здесь - Проблема с оценкойJavaScript()

person Piotr Dobrogost    schedule 17.04.2010

Привет, я знаю, что этот вопрос довольно старый, но я хотел предложить другой ответ. Вы сказали: "...поскольку элемент не отображается на экране, он не может сделать математику, чтобы щелкнуть его...". Что ж, "это" не умеет считать, а "Вы" можете. ;) Вы можете получить позицию элемента, на который хотите щелкнуть, и рассчитать, сколько пикселей (X) вам нужно прокрутить вниз/вверх, чтобы сделать его видимым. Затем вы можете автоматически прокрутить страницу на X пикселей и использовать значение X для расчета текущей позиции элемента и щелкнуть там. Та же логика используется, если вам также нужно прокручивать влево или вправо. Просто используйте Y пикселей в качестве значения горизонтальной коррекции. Я сделал это на другом языке, и я знаю, что это выполнимо и работает нормально. :)

РЕДАКТИРОВАНИЕ: (21 февраля 2013 г.)

Хорошо, я должен был сделать это и для одного из моих проектов. Итак, чтобы проиллюстрировать то, что я имел в виду выше, ниже приведен код 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 не работает. Я надеюсь, что это будет полезно и кому-то еще.

person dv8    schedule 04.02.2013
comment
Потрясающий! Для тех, кто запускает свой QWebPage в фоновом режиме (и, следовательно, у них нет QWebView), использование webPage.currentFrame()->documentElement().geometry() для получения web->width() и web->height() также будет работать! - person hytromo; 23.04.2014

Для тех, кто хочет нажать кнопку Webview, выполните следующие действия.

frame1->evaluateJavaScript( "document.forms[0].submit();" ); 
person Kashyap    schedule 26.06.2012
comment
Хорошо ответ, может быть какое-то объяснение? - person quantum; 20.10.2012