【QtDesigner】PyQt5 で WebView を実装する

# PyQt5 で WebView を実装してみる

`QtDesigner` と `PyQt5` を用いて、簡易的なブラウザを作成しようと思い立ったのですが、
WebView を表示するための設定方法について、日本語の記事がなかなか見つからなかったため、備忘録としてここに残しておきます。

## 環境

- OS: MacOS Catalina 10.15.3

- QtDesigner: version 5.9.6

- PyQt5: version 5.15.0


## 結論
- WebView は、**Qt5.6 で削除された**。

- 代わりに、**QwebEngineView** を使用する必要がある。

- **QWebEngineView** を使用するには、 **QWidget を拡張して、QWebEngineView クラスを作成する**必要がある。

## 背景

冒頭でもさらっと書いた通り、簡易的なブラウザを作成しようと思い立ちました。
色々ググってみた結果、 `PyQt5` というライブラリを使用すれば `Python` でもわりと簡単に Web ページを表示する機能を実装できそうだということで、
こちらのライブラリを使用してとりあえずやってみることにしました。

### WebView という Widget が存在しない

`PyQt5` を調べていくうちに、`QtDesigner` という便利なレイアウトツールの存在を知りました。
せっかくですし、このツールも使用してブラウザを作成していくことにしました。

しかし、Web ページを表示するために必要な WebView Widget が見当たりません。
様々なチュートリアル記事には、「WebView Widget を設置します」という感じでさらっと、Web ページを表示していました。
しかし、少なくとも私が使用している QtDesigner には、WebView Widget も、WebEngineView も見つけることができませんでした。

前置きが長くなってしまいましたが、なんとか解決することができたので、その方法を以下に書いていきます。

## QWidget を設置する

まずは、`QtDesigner` で新しいプロジェクトを作成します。
今回は、MainWindow を選択しています。

![85CE9144-5FC2-4114-A57C-44DD6919D0EB.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485313/50e37b2e-8160-64d3-1e3e-f8577c076d7e.jpeg)

次に、作成した MainWindow に Widget を設置します。

![628BE789-5505-49B8-9FEC-441953EACE30_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485313/f12c66b4-869c-0e0b-58f8-5e830c40ce31.jpeg)


設置した Widget 上で右クリックして、「**Promote to**」を選択します。


![50F32B8E-F067-4AEE-B52E-08D28E00E865.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485313/2b3f78a9-c2af-cca0-0e8c-9a3b9d1d46da.jpeg)

ダイアログが表示されるので、以下のように入力し、Add します。

- Base class name
    - QWidget
- Promoted class name
    - QWebEngineView
- Header file
    - qwebengineview.h
- Global include
    - チェックを入れる


![679F4CD9-0BF3-4557-8975-10D248DD848E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485313/d104f15e-769e-72ab-5199-abe9f57b48bc.jpeg)

`QtDesigner` での操作は以上です。
作成した UI は保存します。
次は、`.ui` ファイルを `.py` ファイルに変換し、コードに修正を加えていきます。

## pyuic5 を用いて、.ui 形式のファイルを .py 形式のファイルに変換する。

`pyuic5` とは、`QtDesigner` 上で作成した `.ui` 形式のファイルを、`Python` 形式のファイルに変換をしてくれるツールです。
`PyQt5` をインストールしたときに一緒にインストールされるみたいです。

```
pyuic5 -o WebViewSample.py WebViewSample.ui
```
## .py 形式の UI ファイルに修正を加えていく

`pyuic5` を用いて `.ui` 形式のファイルを `.py` 形式のファイルに変換を行うと、以下のようなコードが生成されます。

```WebViewSample.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'WebViewSample.ui'
#
# Created by: PyQt5 UI code generator 5.15.0
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        # 以下が先ほど作成した Widget
        self.widget = QtWebEngineWidgets.QWebEngineView(self.centralwidget)
        self.widget.setGeometry(QtCore.QRect(20, 10, 761, 531))
        self.widget.setObjectName("widget")
        # 追加ここまで

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
from PyQt5 import QtWebEngineWidgets

```

上記の `setupUi` ファンクションの中に以下のコードを追加します。
確認用に、起動時にアクセスする Web ページを指定します。

```addScipt.py
url = "https://www.google.co.jp"
self.widget.setUrl(QtCore.QUrl(url))
```

## 実行用ファイルを作成する

```BrowserSample.py
import sys
from PyQt5 import QtWidgets
from WebViewSample import Ui_MainWindow

class Browser(QtWidgets.QMainWindow):
  def __init__(self,parent=None):
    super(Browser, self).__init__(parent)
    self.ui = Ui_MainWindow()
    self.ui.setupUi(self)
 
if __name__ == '__main__':
  app = QtWidgets.QApplication(sys.argv)
  window = Browser()
  window.show()
  sys.exit(app.exec_())
```

上記のファイルを実行する。


![1174F72A-C32A-4EA1-854B-56BB285239E0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485313/3cb226d5-674c-291e-f8fc-bb97c7f59c93.jpeg)

とりあえず表示することができました。
ここから、色々とカスタマイズしていこうと思います。

## 参考

[QtForum: QWebEngineView in QtDesigner](https://forum.qt.io/topic/65398/qwebengineview-in-qtdesigner)
[living-sun.com: Qt WebEngineView is not available for creators, but qt, qt-creator, qt-designer, qwebengineview](https://living-sun.com/ja/qt/735369-qt-webengineview-not-available-in-creator-but-available-in-designer-qt-qt-creator-qt-designer-qwebengineview.html)