QtWebView C++ Как получить строку javascript, возвращаемую из события linkClicked

Я не смог найти окончательного ответа на свою проблему.

В настоящее время у меня есть элемент управления QWebView, загружающий html-файл, который находится на моем жестком диске, который реализует векторную карту с действиями javascript. Файл html загружает карту штатов США jvectormap. Действие щелчка в любом состоянии запускает действие onRegionClick, привязанное к функции showCities, аргументы события и кода которой обрабатываются методом onRegionClick, реализованным в файле jquery-jvectormap.js. HTML-файл выглядит следующим образом:

<!DOCTYPE html>

<html lang="en">
<head>

    <link rel="stylesheet" href="styles/style2.css" type="text/css"/>


    <link rel="stylesheet" media="all" href="styles/jquery-jvectormap.css"/>
    <script src="js/jquery.tools.min.js"></script>
    <script src="js/jquery-jvectormap.js"></script>
    <script src="js/jquery-jvectormap-us-en.js"></script>
    <script>
        $(function() {
            $('.map').vectorMap({
                map: 'us_en',
                color: 'green',
                hoverColor: 'blue',
                onRegionClick: showCities
            });
        });
        function showCities(event, code) {
            return code;

        }


    </script>
</head>


<body>



    <div id="front">


        <div class="map"></div>

        </div>


</body>
</html>

И информация о заголовочном файле mainwindow.h в Qt:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QUrl>
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:

    void on_webView_linkClicked(const QUrl &arg1);


private:
    Ui::MainWindow *ui;

};

#endif // MAINWINDOW_H

А затем файл MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QtGui>
#include <QtCore>
#include <QDebug>
#include <QtWebKit>
#include <QWebSettings>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
   ui->setupUi(this);
   ui->webView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
   ui->webView->settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
   connect(ui->webView,SIGNAL(linkClicked(QUrl)),this,SLOT(on_webView_linkClicked(QUrl)));

}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_webView_linkClicked(const QUrl &arg1)
{
    QMessageBox::information(this,"Title","Test");

}

Функция on_webView_linkClicked не запускается/запускается, когда я нажимаю на какую-либо конкретную область региона. Любая область, по которой щелкнули, предназначена для возврата строки. Когда я пробую это на веб-странице, например http://www.google.com, QMessageBox в функции on_WebView_linkClicked фактически запускает/запускает событие, которое показывает QMessageBox.

Цель здесь состоит в том, чтобы получить строку javascript, возвращенную в файле html в функции showCities, для отображения в событии on_webView_linkClicked. По-видимому, действие linkClicked не распознает возврат javascript в качестве ссылки, поэтому при использовании векторной карты jquery оно молчит.

Я везде искал это, и единственный ответ, который я могу получить, заключается в том, что если к этим регионам в векторной карте были прикреплены URL-ссылки, это могло бы сработать, но мое встраивание фиктивных ссылок в эти регионы не приводит к срабатыванию события on_webView_linkClicked.

Спасибо за все что ты сделал для меня :)


person user1793027    schedule 02.01.2013    source источник


Ответы (2)


Вы можете внедрить QObject (например, ваш MainWindow) в JavaScript. Как только ваша функция JavaScript вызывается, вы можете передать этот вызов внедренному объекту.

Не полный код, но чтобы дать представление:

MainWindow.h

class MainWindow : public QMainWindow
{
    Q_OBJECT

    ...

public slots:

    void jsInjection();

    void showCities(const QString &code);
}

MainWindow.cpp

MainWindow::MainWindow()
{
    ...

    connect(ui->webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
            this, SLOT(jsInjection()));
}

void MainWindow::jsInjection()
{
    ui->webView->page()->mainFrame()->addToJavaScriptWindowObject("qtMainWindow", this);
}

void MainWindow::showCities(const QString &code)
{
    // Do smth with code...
}

в HTMLJS

function showCities(event, code) {
    qtMainWindow.showCities(code);
}
person Archie    schedule 02.01.2013
comment
Спасибо Арчи - я попробую это и посмотрю, как это работает. Я видел подобные примеры, но ничего особенного. Еще раз спасибо - я бы +1 вам за это, но у меня пока недостаточно учетных данных в StackOverflow, чтобы сделать это, поэтому, если кто-то еще может сделать это для Арчи, я ценю это. - person user1793027; 03.01.2013
comment
Просто для обновления - Арчи дал лучший ответ на этот вопрос. Надеюсь, кто-нибудь когда-нибудь столкнется с этим, и это будет полезно — для всех пользователей StackOverflow, которым разрешено ставить +1 к ответу, пожалуйста, сделайте это, чтобы он мог получить признание там, где это необходимо. Еще раз спасибо, Арчи :) - person user1793027; 03.01.2013

ИМХО, следующее решение проще:

главное окно.h

protected slots:
    void showCities();

главное окно.cpp

//in constructor
//make sure that page already loaded
webView->page()->mainFrame()->addToJavaScriptWindowObject("qt", this);


// implement function
void MainWindow::showCities()
{
    // do what you want to do
}

abc.js

qt.showCities();
person Tyler Long    schedule 24.02.2014