初心者でも絶対出来る自作ブラウザ[Python]第7章 PDF表示
今日は初心者でも絶対出来る自作ブラウザ[Python]シリーズで紹介してきた自作ブラウザについてリクエスト頂いたので、PDFの表示について紹介します。
実現方法の検討
まずは、PythonでPDFの表示に使えそうなライブラリを探してみました
ReportLab | PDFの生成 |
PyPDF2 | PDFの分割結合、パスワード追加等 |
PyPoppler | PDFからのテキスト抽出等 |
PDFMiner | PDFからのテキスト抽出等 |
PyPopplerがQtとの連携もしやすいようなので、これを使えば簡単にできるかな?
ということでPyPopplerをQtで作成したブラウザに組み込む方法を調べました
QtでのPDFへの対応
調べてみるとなんと、、、
Qtの5.13からPDFドキュメントをダウンロードせずに、内部PDFビューアーで開くことができるようになったそうです!!
pyqtのバージョンアップ
まずはインストール済みのpyqtのバージョンを確認します
AnacondaPromptを起動して、ブラウザ用の仮想環境に入ります
私の場合は、以下のフォルダに仮想環境を入れています
C:\ProgramData\Anaconda3\envs\browser\Scripts\activate
次に、インストール済みのライブラリを確認するpip listを実行します
PyQt5とPyQtWebEngineのバージョンが5.13より古い場合はpip install -U PyQt5とpip install -U PyQtWebEngineを実行して最新版にバージョンアップします
ソースの変更箇所
今回の修正はデザイナーから自動生成したUIのPythonファイルだけです
ソースの全体は以下です
# -*- 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
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
import time
class Ui_MainWindow(object):
def CreatePage(self, MainWindow, name):
self.basePage = QtWidgets.QWidget()
self.basePage.setObjectName(name)
self.gridLayout = QtWidgets.QGridLayout(self.basePage)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton = QtWidgets.QPushButton(self.basePage)
self.pushButton.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("res/back.bmp"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.pushButton.setIcon(icon)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.pushButton_2 = QtWidgets.QPushButton(self.basePage)
self.pushButton_2.setText("")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap("res/forward.bmp"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.pushButton_2.setIcon(icon1)
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout.addWidget(self.pushButton_2)
self.pushButton_3 = QtWidgets.QPushButton(self.basePage)
self.pushButton_3.setObjectName("pushButton_3")
self.horizontalLayout.addWidget(self.pushButton_3)
self.closeButton = QtWidgets.QPushButton(self.basePage)
self.closeButton.setObjectName("closeButton")
self.horizontalLayout.addWidget(self.closeButton)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.pushButton_4 = QtWidgets.QPushButton(self.basePage)
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.basePage)
self.label.setObjectName("label")
self.horizontalLayout_2.addWidget(self.label)
self.lineEdit = QtWidgets.QLineEdit(self.basePage)
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout_2.addWidget(self.lineEdit)
self.verticalLayout.addLayout(self.horizontalLayout_2)
self.webEngineView = QtWebEngineWidgets.QWebEngineView(self.basePage)
self.webEngineView.page().settings().setAttribute( QWebEngineSettings.PluginsEnabled, True)
self.webEngineView.page().settings().setAttribute( QWebEngineSettings.PdfViewerEnabled, True)
initurl = 'https://www.google.co.jp'
self.webEngineView.setUrl(QtCore.QUrl(initurl))
self.webEngineView.setObjectName("webEngineView")
self.verticalLayout.addWidget(self.webEngineView)
self.verticalLayout_2.addLayout(self.verticalLayout)
self.gridLayout.addLayout(self.verticalLayout_2, 0, 0, 1, 1)
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.titleChanged['QString'].connect(MainWindow.urlLineSet)
self.closeButton.clicked.connect(MainWindow.closeTab)
self.retranslateUi(MainWindow)
return self.basePage
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(840, 768)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
self.gridLayout_2.setObjectName("gridLayout_2")
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
self.tabWidget.setTabsClosable(False)
self.tabWidget.setObjectName("tabWidget")
tabName = "page"+str(time.time())
self.page = self.CreatePage(MainWindow, tabName)
self.pageNameList = list()
self.pageNameList.append(tabName)
self.tabWidget.addTab(self.page, "新しいタブ")
self.addPage = QtWidgets.QWidget()
self.addPage.setObjectName("addPage")
self.tabWidget.addTab(self.addPage, "")
self.gridLayout_2.addWidget(self.tabWidget, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 840, 17))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
_translate = QtCore.QCoreApplication.translate
self.tabWidget.setTabText(self.tabWidget.indexOf(self.addPage), _translate("MainWindow", "+"))
self.tabWidget.setCurrentIndex(0)
self.tabWidget.tabBarClicked['int'].connect(MainWindow.newTab)
MainWindow.setWindowTitle(_translate("MainWindow", "pyQtBrowser"))
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
self.closeButton.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
修正箇所は3個所だけです
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
QWebEngineSettingsを使用するのでインポートしています
self.webEngineView.page().settings().setAttribute( QWebEngineSettings.PluginsEnabled, True)
self.webEngineView.page().settings().setAttribute( QWebEngineSettings.PdfViewerEnabled, True)
webEngineViewのsettingsで以下の2つをTRUEに設定しています
PluginsEnabled: FlashプレーヤーなどのPepperプラグインのサポートを有効にします。
PdfViewerEnabled: PDFドキュメントをダウンロードせずに、内部PDFビューアーで開くことを指定します
QWebEngineSettingsについて詳しく知りたい方は下記のURLを参考にしてください
https://translate.googleusercontent.com/translate_c?depth=1&hl=ja&prev=search&rurl=translate.google.com&sl=en&sp=nmt4&u=https://doc.qt.io/qt-5/qwebenginesettings.html&xid=17259,15700023,15700186,15700190,15700256,15700259,15700262,15700265,15700271,15700280,15700283&usg=ALkJrhig5F2B3X7jeuC7Dr6RBFATTTEIDw#WebAttribute-enum
PDFの表示
修正が完了したらさっそく実行してみます
適当にPDFのページを検索して開いてみます
まとめ
今回はPDFの表示についてでした。
思いがけず、Qtの方で対応してくれていたので、簡単に出来ました。
今後も質問や相談あればドシドシご連絡ください!!
こんなの作ってみたい等の依頼も募集してますよ~
ディスカッション
コメント一覧
self.closeButton.clicked.connect(MainWindow.closeTab)
のところでエラーが起こります。
「例外が発生しました: AttributeError
‘browserUI’ object has no attribute ‘closeTab’
File “C:\Users\〇〇〇\Desktop\Program\Super Browser\browser2Ui.py”, line 81, in CreatePage
self.closeButton.clicked.connect(MainWindow.closeTab)
File “C:\Users\〇〇〇\Desktop\Program\Super Browser\browser2Ui.py”, line 99, in setupUi
self.page = self.CreatePage(MainWindow, tabName)
File “C:\Users\〇〇〇\Desktop\Program\Super Browser\browser2.py”, line 10, in __init__
self.ui.setupUi(self)
File “C:\Users\〇〇〇\Desktop\Program\Super Browser\browser2.py”, line 20, in
window = browserUI()」
と表示されます。VSCodeです。
81行目の「self.closeButton.clicked.connect(MainWindow.closeTab)」
でなんかエラーが起きました。
「例外が発生しました: AttributeError
‘browserUI’ object has no attribute ‘closeTab’」
と表示されます。属性って何のことですか?
助けてください。
browserUIにcloseTabがないよというエラーですね
デザイナーで作成したさいにタブは配置されましたか?
まだです。
このサイトの通りにしたのですが、うまくいかなくて。
7章に載っているとおりに修正したのですが。
すみません。
6章で作成したタブ機能がないのにそこら辺の記述が邪魔しているのだと思います。
今回重要なのは下記となりますので、5章までできていれば、それに下記を追加でもいいかと思います。
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
self.webEngineView.page().settings().setAttribute( QWebEngineSettings.PluginsEnabled, True)
self.webEngineView.page().settings().setAttribute( QWebEngineSettings.PdfViewerEnabled, True)
6章で作成したものにそれを追加すればよいのでしょうか?
6章の通りにやりました。
それで7章の通りにしたのですが、うまくいきません。