Qt最新事情-QtでWebKitを使ってみよう

第6回 Qt WebKit~WebコンテンツとQtの連携

この記事を読むのに必要な時間:およそ 11 分

まず,HTMLの記述を説明しましょう。

リスト1 form.html

01: <html><script>
02: function extractFormValues()

27行目で,サブミット時にこの関数を呼び出すようにしています。

03: {
04:     var firstName = document.getElementById("firstname").value;
05:     var lastName = document.getElementById("lastname").value;
06:     var maleGender = document.getElementById("genderMale");
07:     var femaleGender = document.getElementById("genderFemale");
08:     
09:     var gender = "";
10:     if (maleGender.checked)
11:         gender = maleGender.value;
12:     else if (femaleGender.checked)
13:         gender = femaleGender.value;
14:         
15:     var updates = document.getElementById("updates").checked;

入力項目には以降のように,idをfirstname,lastname,genderMale,genderFemale,updatesにしているので,idから入力値を得ておきます。

16:         
17:     formExtractor.setValues(firstName, lastName, gender, updates);

formExtractorは,Qt/C++のオブジェクトがバインドされたJavaScriptオブジェクトで,setValues()は後述するQt/C++のFormExtractorクラスのスロットメソッドにバインディングされています。ここでsetValues()を呼び出すと,Qt/C++側のsetValues()が呼び出されて,Qt/C++側で入力値を得られることになります。

19: </script><body>
20: <h1>
21: The Green People Book Club
22: </h1>
23: 
24: <p>
25: Welcome to The Green People Book Club. Please register to obtain a membership with us.
26: </p>
27:     <form onsubmit="extractFormValues()">
28:     <table>
29:     <tbody><tr>
30:         <td>
31:         First name:
32:         </td>
33:         <td>
34:             <input type="text" id="firstname">
35:         </td>
36:     </tr>
37:     <tr>
38:         <td>
39:         Last name:
40:         </td>
41:         <td>
42:             <input type="text" id="lastname">
43:         </td>
44:     </tr>
45:     <tr>
46:         <td>
47:         Gender:
48:         </td>
49:         <td>
50:         <input type="radio" name="gender" id="genderMale" value="Male"> Male
51:         <input type="radio" name="gender" id="genderFemale" value="Female"> Female
52:         </td>
53:     </tr>
54:     <tr>
55:         <td colspan="2">
56:         <input type="checkbox" id="updates" value="receive">
57:         Check here if you would like to receive regular updates from us:
58:         </td>
59:     </tr>
60:     </tbody></table>
61:     <input type="submit" value="Submit">
62:     </form>
63: 
64: </body></html>

リスト2 formextractor.h

53: public slots:
54:     void setValues(const QString &firstName, const QString &lastName,
55:                    const QString &gender, bool updates);

setValues()は,スロットですがQt/C++内ではシグナルから接続されていませんし,直接呼び出しもされていません。Qtのオブジェクトモデルの機能によって,JavaScriptから呼び出せるように実装されているスロットで,第3回で説明したQMetaObject::invokeMethod() を使って呼び出せるようにするために,スロットにしています。

56: 
57:     void populateJavaScriptWindowObject();

リスト3 formextractor.cpp

40: FormExtractor::FormExtractor(QWidget *parent, Qt::WFlags flags)
41:     : QWidget(parent, flags)
42: {
43:     ui.setupUi(this);
44:     ui.webView->setUrl(QUrl("qrc:/form.html"));
45:     connect(ui.webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
46:             this, SLOT(populateJavaScriptWindowObject()));
47:     resize(300, 300);
48: }

シグナルQFrame::javaScriptWindowObjectCleared()が送信されるのは,URLをロードする前で,JavaScript環境のグローバルなウィンドウオブジェクトがクリアーされるときです。したがって,このシグナルが送信されるタイミングで,QWebFrame::addToJavaScriptWindowObject()を呼び出して,Qt/C++のオブジェクトをJavaScriptからアクセスできるようにすればよいことになります。

54: void FormExtractor::setValues(const QString &firstName, const QString &lastName,
55:                               const QString &gender, bool updates)
56: {
57:     ui.firstNameEdit->setText(firstName);
58:     ui.lastNameEdit->setText(lastName);
59:     ui.genderEdit->setText(gender);
60: 
61:     if (updates == false)
62:         ui.updatesEdit->setText("No");
63:     else
64:         ui.updatesEdit->setText("Yes");
65: }

前述のように,JavaScriptから呼び出されるスロットで,Webフォームから渡されてきた値を図4の右側に表示しています。

67: void FormExtractor::populateJavaScriptWindowObject()
68: {
69:     ui.webView->page()->mainFrame()->addToJavaScriptWindowObject("formExtractor", this);
70: }

このインスタンス自身をJavaScript環境のフレームのウィンドウオブジェクトに追加しています。このようにすることで,JavaScriptからQt/C++のFormExtractorのインスタンスのスロットを呼び出せるようになります。

著者プロフィール

杉田研治(すぎたけんじ)

1955年生まれ。東京都出身。株式会社SRAに勤務。プログラマ。

仕事のほとんどをMac OS XとKubuntu KDE 4でQtと供に過ごす。