最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

qt - QWebFrame addToJavaScriptWindowObject() objects are undefined in Javascript - Stack Overflow

programmeradmin0浏览0评论

I have started to dig in to C++ and Qt again, and have been mucking around with the WebKit Javascript/Qt bindings. I've got all the moving parts working, with the exception of my QObject subclass being "undefined" on the Javascript side. Here's the simple test app I'm having trouble with:

My main window implementation:

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

};

The above-mentioned index.html file does a simple alert(Hello.say()) call, but doing typeof Hello, I get undefined.

I'm a bit rusty with C++, and pretty new to Qt, so I'm sure this is a noob mistake, but I'm stumped.

I have started to dig in to C++ and Qt again, and have been mucking around with the WebKit Javascript/Qt bindings. I've got all the moving parts working, with the exception of my QObject subclass being "undefined" on the Javascript side. Here's the simple test app I'm having trouble with:

My main window implementation:

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

};

The above-mentioned index.html file does a simple alert(Hello.say()) call, but doing typeof Hello, I get undefined.

I'm a bit rusty with C++, and pretty new to Qt, so I'm sure this is a noob mistake, but I'm stumped.

Share Improve this question asked Aug 21, 2011 at 23:03 KyleKyle 1,0543 gold badges14 silver badges27 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

Objects can't be inserted in the page at any time. You should put that line:

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

in a slot connected to the javaScriptWindowObjectCleared() signal of the QWebFrame and move some code around, so you can access the frame from that slot.

See also the Form Extractor example included with Qt.

The core of this is really implemented in two methods, which are shown below:

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 );
}

This code is all that you need in order to make all of the public slots of the MyApi object visible to javascript. The MyApi class provides two public slots:

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

The first slot simply logs a message to the debug output, the second returns the sum of its two arguments (yes, slots can return things!). They're called from javascript like this:

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

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

The code above was tested in QT5.5, and please note all methods should be put in "public slots" section.

发布评论

评论列表(0)

  1. 暂无评论