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

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

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

地図の表示

図5の画面レイアウトはQt Designerで作成されていて,左側の住所の一覧にはQTreeViewが使われ,右側の地図にはQWebViewを継承したクラスMapが使われています。Mapではurlプロパティに以下のURLを指定して,世界地図が初期表示されるようにしています。

  • http://chaos.troll.no/~hhartz/visualaccess/index.html

このURLの記述内容は,Google Maps APIキーの登録完了時に示されるHTML記述で,数ヵ所を変更してこのサンプルに合うようにしています。住所はファイルaddresses.txtに記述されていて,内容はリスト5のようになっています。カンマ区切りで2番目以降のフィールドが住所です。

リスト5 addresses.txt

Qt Software Oslo, Sandakerveien 116, 0402 OSLO, Norway
Qt Software Brisbane, Brisbane, Australia
Qt Software Silicon Valley, Redwood City, CA 94065, USA
Qt Software China, Beijing, China
Qt Software Berlin, Berlin, Germany
Qt Software Munich, Munich, Germany
技術評論社, 東京都新宿区市谷左内町21-13

この内容をQTreeViewに表示するために,リスト6でQStandardItemModelを継承したAddressModelを作成しています。

リスト6 addressmodel.h

14:         void initModel()
15:         {
16:             foreach ( QString address, this->addresses() ) {
17:                 QModelIndex idx = this->index( this->rowCount(), 0 , QModelIndex() );
18: 
19:                 QStringList addressLines = address.split( "," );
20: 
21:                 QStandardItem* item = new QStandardItem;
22:                 this->insertRow( this->rowCount(), item );
23: 
24:                 item->setData( addressLines.first(), Qt::DisplayRole );
25:                 addressLines.removeFirst();
26: 
27:                 item->setData( addressLines.join( "," ).trimmed(), Qt::UserRole );
28:             }
29:         }

1番目のフィールドをQTreeViewに表示し,Qt::UserRoleに住所をデータとして格納しています。

31:         QStringList addresses() {
32:             QFile file( "addresses.txt" );
33:             if( file.open( QFile::ReadOnly) ) {
34:                 QString addressText = QString::fromUtf8( file.readAll() );
35:                 addressText.chop( 1 );
36:                 return addressText.split( QChar( '\n' ) );
37:             }
38:             return QStringList();
39:        }

ファイル全体を読み込んで,改行コードで分割してQStringのQListで返しています。日本語住所を扱えるようにするために,QString::fromUtf8()を元のコードに対して追加しています。

リスト7 mainwindow.cpp

11: MainWindow::MainWindow( QWidget* parent, Qt::WFlags flags )
12:     : QWidget( parent, flags )
13: {
14:     ui.setupUi( this );
15: 
16:     ui.treeView->setModel( new AddressModel( this ) );
17:     ui.treeView->header()->setStretchLastSection( true );
18: 
19:     connect( ui.treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(showItem(QModelIndex)) );
20:     ui.map->show();
21: }

QTreeViewにAddressModelを設定して住所の一覧を表示させ,QTreeViewの項目をクリックしたら,showItem()スロットが呼び出されるようにしています。

28: void MainWindow::showItem( const QModelIndex& idx )
29: {
30:     ui.map->clearCoordinates();
31:     ui.map->geoCode( idx.data( Qt::UserRole).toString() );
32:     ui.nameLabel->setText( idx.data( Qt::DisplayRole ).toString() );
33:     ui.addressLabel->setText( idx.data( Qt::UserRole ).toString() );
34: }

先に説明したのと同様に,Map::geoCode()で住所を渡して,地図にマーカが表示されるようにしています。

リスト8 map.cpp

51: void Map::loadCoordinates()
52: {
53:     QStringList scriptStr;
54:     scriptStr
55:             << "var map = new GMap2(document.getElementById(\"map\"));"
56:             << "var bounds = new GLatLngBounds;"
57:             << "var markers = [];"
58:             << "map.setCenter( new GLatLng(0,0),1 );";
59: 
60:     int num=-1;
61:     foreach( QPointF point, coordinates ) {
62:         scriptStr << QString("markers[%1] = new GMarker(new GLatLng(%2, %3));")
63:                              .arg(++num)
64:                              .arg(point.x())
65:                              .arg(point.y());
66:     }
67: 
68:     scriptStr
69:             << "for( var i=0; i<markers.length; ++i ) {"
70:             << "   bounds.extend(markers[i].getPoint());"
71:             << "   map.addOverlay(markers[i]);"
72:             << "}"
73:             << "map.setCenter(bounds.getCenter());";
74: 
75: 
76:     this->page()->mainFrame()->evaluateJavaScript( scriptStr.join("\n") );
77: }

得られた地理座標から地図上にマーカを表示し,センタリングをするために,QWebFrame::evaluateJavaScript()でJavaScriptのコードを実行しています。

著者プロフィール

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

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

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