QWebFrame addToJavaScriptWindowObject () объекты не определены в Javascript - PullRequest
3 голосов
/ 22 августа 2011

Я снова начал копаться в C ++ и Qt, и я начал копаться в привязках WebKit Javascript / Qt. У меня работают все движущиеся части, за исключением того, что мой подкласс QObject не определен на стороне Javascript. Вот простое тестовое приложение, с которым у меня проблемы:

Моя реализация основного окна:

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

// instantiate a webview
QWebView *webview = new QWebView(this);
webview->setGeometry(0, 0, 400, 300);
webview->setUrl(QUrl("file://localhost/Users/kyle/Sites/tests/qt/index.html"));

// instantiate and attach our QObject
hello *h = new hello();

QWebFrame *frame = webview->page()->mainFrame();
frame->addToJavaScriptWindowObject("Hello", h);

// show the window
webview->show();
}

hello.cpp

...snip...

QString hello::say()
{
    return QString("Kyle");
}

hello.h

...snip includes...

class hello : public QObject
{
    Q_OBJECT

public:
    hello();
    Q_INVOKABLE QString say();

};

Вышеупомянутый файл index.html выполняет простой alert(Hello.say()) вызов, но, выполнив typeof Hello, я получаю неопределенное значение.

Я немного заржавел с C ++ и довольно плохо знаком с Qt, так что я уверен, что это ошибка новичка, но я в замешательстве.

Ответы [ 2 ]

6 голосов
/ 24 августа 2011

Объекты не могут быть вставлены на страницу в любое время.Вы должны поместить эту строку:

frame->addToJavaScriptWindowObject("Hello", h);

в слот, подключенный к сигналу javaScriptWindowObjectCleared() QWebFrame и переместить некоторый код, чтобы вы могли получить доступ к кадруslot.

См. также пример извлечения формы , включенный в Qt.

0 голосов
/ 22 июля 2015

Суть этого действительно реализована в двух методах, которые показано ниже:

void MyApi::setWebView( QWebView *view )
{
    QWebPage *page = view->page();
    frame = page->mainFrame();

    attachObject();
    connect(frame, &QWebFrame::javaScriptWindowObjectCleared, this, &MyApi::attachObject);
    // old approach
    //connect( frame, SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(attachObject()) );
}

void MyApi::attachObject()
{
    frame->addToJavaScriptWindowObject( QString("MyApi"), this );
}

Этот код - все, что вам нужно для того, чтобы сделать все открытые слоты Объект MyApi видимый для JavaScript. Класс MyApi предоставляет два открытых слота:

public slots:
    void doSomething( const QString &param );
    int doSums( int a, int b );

Первый слот просто записывает сообщение на выход отладки, второй возвращает сумма двух аргументов (да, слоты могут возвращать вещи!). Они называются из JavaScript, как это:

MyApi.doSomething( 'Hello from JS page 2!!!!' );

sum = MyApi.doSums( 2, 3 );
alert( 'C++ says the sum is ' + sum );

Приведенный выше код был протестирован в QT5.5, и обратите внимание, что все методы должны быть помещены в раздел "public slots".

...