今日はブラウザを1から作ってみたいシリーズの第6弾のボタンの動作作成です
今回も初心者でも絶対できるように細かく説明していきます
このシリーズを読んでいけば以下のことができるようになります
- 仕様検討
- Pythonの環境構築構築
- Pythonのライブラリの導入方法
- Pythonでの開発
- 自作ブラウザの表示
- ブラウザのカスタマイズ ←この記事
前回の記事ではブラウザのGUIをデザインしてボタンなどを作成しました
前回はデザインのみでしたので、作成したボタンを押しても何も起きない状態でした
今回はボタンを押した時にちゃんと動作するように実装していきます
シグナルとスロットについて
Qtでは独自のシグナルとスロットという仕組みを用いてイベント処理を行います
シグナルがユーザがマウスやキーボードを使用して実行する動作を定義したものです
スロットがシグナルが発生した時に実行したい処理内容となります
このシグナルとスロットを組み合わせることをコネクトと呼びます
例えば、「戻るボタンを押す」と「1つ前のページに戻る」動作を行う場合 シグナルが「戻るボタンを押す」で スロットが「1つ前のページに戻る」となりますシグナルとスロットについて詳しく知りたい方は以下のQtのサイトをご覧ください
https://doc.qt.io/qt-5/signalsandslots.html
Qt Designerでのシグナルとスロット作成
Qt Designerを実行して前回のUIを開きます
画面ジョブのシグナル/スロットを編集ボタンを押します
シグナルとスロットの編集モードになりますので設定します
設定方法はユーザが操作するアイテムをクリックした状態で、処理を実行するアイテム上にマウスを移動させて離します
例えば戻るボタンを押して1つ前のページに戻る際には
ユーザが操作するのは「戻るボタン」で、処理を実行するのはwebEngineViewです
戻るボタンをwebEngineViewにドラッグ&ドロップ するようなイメージです
ドラッグ&ドロップ すると以下の画面が開きますので、ここでシグナルをスロットを選びます
標準でよく使用するものが用意されています
左がシグナルとなっており、ここではボタンのクリック(clicked())を選択します
右がスロットとなっており、ここでは戻る(back())を選択します
戻る、進む、更新ボタンのclicked()にそれぞれback()、forward()、reload()を設定します
設定が完了したら、前回同様.uiファイルから.pyファイルに変換してください
今回シグナルとスロットを追加したことにより以下の行が追加されています
アイテム.シグナル.connect(スロット)という形で記述されます
self.pushButton_2.clicked.connect(self.webEngineView.forward)
self.pushButton.clicked.connect(self.webEngineView.back)
self.pushButton_3.clicked.connect(self.webEngineView.reload)
ソース上でのスロット作成
上のソースコードに自作のスロットを追加したbrowser2UI.pyの全体が以下となります
前回同様、初期ページ設定の以下もお忘れなく!!
initurl = ‘https://www.google.co.jp’
self.webEngineView.setUrl(QtCore.QUrl(initurl))
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'browser2.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
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")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout.addWidget(self.pushButton_2)
self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_3.setObjectName("pushButton_3")
self.horizontalLayout.addWidget(self.pushButton_3)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_4.setObjectName("pushButton_4")
self.horizontalLayout.addWidget(self.pushButton_4)
self.verticalLayout.addLayout(self.horizontalLayout)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setObjectName("label")
self.horizontalLayout_2.addWidget(self.label)
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout_2.addWidget(self.lineEdit)
self.verticalLayout.addLayout(self.horizontalLayout_2)
self.webEngineView = QtWebEngineWidgets.QWebEngineView(self.centralwidget)
initurl = 'https://www.google.co.jp'
self.webEngineView.setUrl(QtCore.QUrl(initurl))
self.webEngineView.setObjectName("webEngineView")
self.verticalLayout.addWidget(self.webEngineView)
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 17))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.pushButton_2.clicked.connect(self.webEngineView.forward)
self.pushButton.clicked.connect(self.webEngineView.back)
self.pushButton_3.clicked.connect(self.webEngineView.reload)
self.lineEdit.returnPressed.connect(MainWindow.webPageUpdate)
self.webEngineView.urlChanged['QUrl'].connect(MainWindow.urlLineSet)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "pyQtBrowser"))
self.pushButton.setText(_translate("MainWindow", "戻る"))
self.pushButton_2.setText(_translate("MainWindow", "進む"))
self.pushButton_3.setText(_translate("MainWindow", "更新"))
self.pushButton_4.setText(_translate("MainWindow", "お気に入り"))
self.label.setText(_translate("MainWindow", "URL:"))
from PyQt5 import QtWebEngineWidgets
追加したのは以下の2行でそれぞれ
lineEditでエンターキーを押された際にMainWindow.webPageUpdate()を
webEngineViewでURLが変更された際にMainWindow.urlLineSet()を
呼び出す設定です
呼び出す関数についてはbrowser2.pyにて実装します
self.lineEdit.returnPressed.connect(MainWindow.webPageUpdate)
self.webEngineView.urlChanged['QUrl'].connect(MainWindow.urlLineSet)
GUIを呼び出す方のbrowser2.pyは以下となります
import sys
from PyQt5 import QtWidgets
from browser3Ui import Ui_MainWindow
from PyQt5.QtCore import QUrl
class browserUI(QtWidgets.QMainWindow):
def __init__(self,parent=None):
super(browserUI, self).__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def webPageUpdate(self):
self.ui.webEngineView.setUrl(QUrl(self.ui.lineEdit.text()))
def urlLineSet(self, QUrl):
self.ui.lineEdit.setText(self.ui.webEngineView.url().url())
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = browserUI()
window.show()
sys.exit(app.exec_())
def webPageUpdate(self):
self.ui.webEngineView.setUrl(QUrl(self.ui.lineEdit.text()))
webPageUpdate()ではlineEditに入力されたURLをwebEngineViewに設定する処理を行っています
def urlLineSet(self, QUrl):
self.ui.lineEdit.setText(self.ui.webEngineView.url().url())
urlLineSet()ではwebEngineViewで変更されたURLをlineEditにセットする処理を行っています
実行
前回同様browser2.pyを実行します
起動した時にURL:に現在のURLが表示されているのが確認できます
検索を実行していみると、URL:の表示が変わるのが確認できます
戻るや進むボタンでページを行ったり来たりできます
次にURLにこのブログのトップページのURLを入力してエンターキーを押します
見事トップページが表示されました
まとめ
今回はGUIのボタン等を押した際の処理を実装しました
Qtのシグナルとスロットを使用することで、ユーザの操作と処理の実行を簡単に結びつけることができました
自作のスロットを使用して様々な処理を追加することでブラウザの完成度をアップさせていきましょう
質問や相談あればドシドシご連絡ください!!
こんなの作ってみたい等の依頼も募集してますよ~