質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2858閲覧

Python PyQt5 について2つ質問 (右クリック時の画像の保存・検索の高速化)

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/05/29 17:47

編集2021/05/29 18:15

前提・実現したいこと

現在、PythonでWebBrowserソフトを作成しているのですが、2点ほど
調べても理解できないものがありましたので、質問させていただきます。
素人質問ですがお付き合いいただけると幸いです。

1つ目

1つ目はQt WebBrowserを組み込んで起動した際にマウスの右クリックで
表示される
![イメージ説明
これらのメニューを日本語化する方法と
これらのメニューに表示される項目を減らす方法
そしてこれらのメニューに機能を追加することです

現状これらは何もしていなくても追加されており
ボタンがあるだけで動作していない状況です
私はこれらから Back と Forward ReloadやSavepage Open link などを削除し
URLのコピーと画像の保存のみ機能を付け足したいです。

2つ目

2つ目は現状何もいじらず、追加しただけの状態のWebBrowserの検索をより高速化できる方法はあるのか?という疑問です
方法があるようでしたら教えていただけると幸いです。

ソースコード

Python

1from PyQt5.QtCore import * 2from PyQt5.QtWidgets import * 3from PyQt5.QtGui import * 4from PyQt5.QtWebEngineWidgets import * 5from PyQt5.QtPrintSupport import * 6import os 7import sys 8 9class MainWindow(QMainWindow): 10 11 def __init__(self, *args, **kwargs): 12 super(MainWindow, self).__init__(*args, **kwargs) 13 14 15 self.tabs = QTabWidget() 16 17 18 self.tabs.setDocumentMode(True) 19 20 21 self.tabs.tabBarDoubleClicked.connect(self.tab_open_doubleclick) 22 23 24 self.tabs.currentChanged.connect(self.current_tab_changed) 25 26 27 self.tabs.setTabsClosable(True) 28 29 30 self.tabs.tabCloseRequested.connect(self.close_current_tab) 31 32 33 self.setCentralWidget(self.tabs) 34 35 36 self.status = QStatusBar() 37 38 39 self.setStatusBar(self.status) 40 41 42 navtb = QToolBar("ツールバーを非表示") 43 44 45 self.addToolBar(navtb) 46 47 48 back_btn = QAction("1ページ戻る", self) 49 50 51 back_btn.setStatusTip("前のページに戻る") 52 53 54 55 back_btn.triggered.connect(lambda: self.tabs.currentWidget().back()) 56 57 58 navtb.addAction(back_btn) 59 60 61 next_btn = QAction("1ページ前へ", self) 62 next_btn.setStatusTip("次のページに進む") 63 next_btn.triggered.connect(lambda: self.tabs.currentWidget().forward()) 64 navtb.addAction(next_btn) 65 66 67 reload_btn = QAction("更新", self) 68 reload_btn.setStatusTip("ページを再読み込み") 69 reload_btn.triggered.connect(lambda: self.tabs.currentWidget().reload()) 70 navtb.addAction(reload_btn) 71 72 73 home_btn = QAction("ホーム", self) 74 home_btn.setStatusTip("ホームへ戻る") 75 76 77 home_btn.triggered.connect(self.navigate_home) 78 navtb.addAction(home_btn) 79 80 81 navtb.addSeparator() 82 83 84 self.urlbar = QLineEdit() 85 86 87 self.urlbar.returnPressed.connect(self.navigate_to_url) 88 89 90 navtb.addWidget(self.urlbar) 91 92 93 stop_btn = QAction(" ", self) 94 navtb.addAction(stop_btn) 95 96 97 self.add_new_tab(QUrl('http://www.google.com'), 'Homepage') 98 browser = QWebEngineView(self.tabs) 99 100 101 self.show() 102 103 104 self.setWindowTitle("BASIC BROWSER") 105 106 107 def add_new_tab(self, qurl = None, label ="Blank"): 108 109 110 if qurl is None: 111 112 qurl = QUrl('http://www.google.com') 113 114 115 browser = QWebEngineView() 116 117 118 browser.setUrl(qurl) 119 120 121 i = self.tabs.addTab(browser, label) 122 self.tabs.setCurrentIndex(i) 123 124 browser.urlChanged.connect(lambda qurl, browser = browser: 125 self.update_urlbar(qurl, browser)) 126 127 browser.loadFinished.connect(lambda _, i = i, browser = browser: 128 self.tabs.setTabText(i, browser.page().title())) 129 130 131 def tab_open_doubleclick(self, i): 132 133 if i == -1: 134 135 self.add_new_tab() 136 137 138 def current_tab_changed(self, i): 139 140 141 qurl = self.tabs.currentWidget().url() 142 143 144 self.update_urlbar(qurl, self.tabs.currentWidget()) 145 146 147 self.update_title(self.tabs.currentWidget()) 148 149 150 def close_current_tab(self, i): 151 152 153 if self.tabs.count() < 2: 154 155 return 156 157 self.tabs.widget(i).deleteLater() 158 self.tabs.removeTab(i) 159 160 161 def update_title(self, browser): 162 163 164 if browser != self.tabs.currentWidget(): 165 return 166 167 168 title = self.tabs.currentWidget().page().title() 169 170 171 self.setWindowTitle("% s - BASIC BROWSER" % title) 172 173 def navigate_home(self): 174 175 self.tabs.currentWidget().setUrl(QUrl("http://www.google.com")) 176 177 def navigate_to_url(self): 178 179 180 q = QUrl(self.urlbar.text()) 181 182 183 if q.scheme() == "": 184 q.setScheme("http") 185 186 187 self.tabs.currentWidget().setUrl(q) 188 189 def update_urlbar(self, q, browser = None): 190 191 if browser != self.tabs.currentWidget(): 192 193 return 194 195 self.urlbar.setText(q.toString()) 196 197 self.urlbar.setCursorPosition(0) 198 199app = QApplication(sys.argv) 200 201app.setApplicationName("BROWSER") 202 203app.setWindowIcon(QIcon('icon.ico')) 204 205window = MainWindow() 206 207app.exec_()

お願い

本来、プログラムとは参考記事を見ながら四苦八苦して書いていくものだと思うのですが
私は学生のため、その時間があまりありません。
ですので、よろしければサンプルコードなどを詳細に記載していただけるとありがたいです

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

これらのメニューを日本語化する方法と

Qt には文字等のリソース翻訳の仕組みがあります。

 ※ 翻訳リソース作成の為には、対象文字だけではなく、第一引数のcontext 情報が必要です

イメージ説明

追記: .ts ファイルのサンプル

xml

1<?xml version="1.0" encoding="utf-8"?> 2<!DOCTYPE TS> 3<TS version="2.1" language="ja"> 4<context> 5 <name>RenderViewContextMenuQt</name> 6 <message> 7 <source>Forward</source> 8 <translation>進む</translation> 9 </message> 10 <message> 11 <source>Back</source> 12 <translation>戻る</translation> 13 </message> 14</context> 15</TS>

手順

  • 上記のXMLを拡張子 .ts で保存します。文字コードは utf-8
  • 他の文字の翻訳は、サンプルを参考に <message> を増やしてください。
  • lrelease コマンドで .ts ファイルから .qm ファイルを生成

 ※ ない場合は、Qt 開発環境のインストールが必要

  • translater.load で .qm ファイルを読み込む

これらのメニューに表示される項目を減らす方法
そしてこれらのメニューに機能を追加することです

C++ であれば、直接既存のメニューを増減してカスタマイズできますが、
Python に提供されてるクラスでは、必要なメソッドが提供されていない為
右クリック時のイベント自体を捕捉し、独自にメニューを生成する必要がありそうです。

追記: page().createStandardContextMenu() で可能でした。

python

1 2import sys 3from PyQt5.QtCore import Qt, QUrl 4from PyQt5.QtWidgets import ( 5 QApplication, 6 QMainWindow, 7 QMessageBox, 8 QAction, 9 QMenu, 10) 11from PyQt5.QtWebEngineWidgets import ( 12 QWebEngineView, 13 QWebEnginePage, 14) 15 16## 方法1 contextMenuEvent 17# QWebEngineView を継承したサブクラスを作る 18 19class MyWebEngineView(QWebEngineView): 20 21 def showTestDialog(self): 22 QMessageBox.information(self, "Test", f"test action was called") 23 24 def contextMenuEvent(self, event): 25 ## 既存のメニューをカスタマイズする場合 26 menu = self.page().createStandardContextMenu() 27 28 # ここで QMenu メニューをカスタマイズ 29 menu.addSeparator() 30 31 action = QAction("Test") 32 action.triggered.connect(self.showTestDialog) 33 menu.addAction(action) 34 35 menu.aboutToHide.connect(menu.deleteLater) 36 menu.exec_(event.globalPos()) 37 38 39## 方法2 CustomContextMenu 40 41def createWebView(parent): 42 view = QWebEngineView(parent) 43 44 def saveLink(): 45 # 既存のメニューの機能を呼び出し 46 view.triggerPageAction( 47 QWebEnginePage.CopyLinkToClipboard) 48 49 def customContextMenuRequested(pos): 50 ## 新規にメニューを作る場合 51 menu = QMenu(view) 52 53 # ここで QMenu メニューをカスタマイズ 54 action = QAction("Save Link") 55 action.triggered.connect(saveLink) 56 menu.addAction(action) 57 58 menu.aboutToHide.connect(menu.deleteLater) 59 menu.exec_(view.mapToGlobal(pos)) 60 61 # カスタムメニューの為の設定 62 view.setContextMenuPolicy(Qt.CustomContextMenu) 63 view.customContextMenuRequested.connect(customContextMenuRequested) 64 65 return view 66 67 68def main(): 69 app = QApplication(sys.argv) 70 win = QMainWindow() 71 view = MyWebEngineView(win) 72 # view = createWebView(win) 73 74 view.setUrl(QUrl("https://www.google.com/")) 75 win.setCentralWidget(view) 76 win.resize(600, 600) 77 win.show() 78 sys.exit(app.exec_()) 79 80 81if __name__ == '__main__': 82 main() 83

Context Menu (右クリック時のメニュー) のカスタマイズ方法
setContextMenuPolicy により挙動を変更できます。

  • 方法1: setContextMenuPolicy を指定しないデフォルトの挙動では、

 派生クラスを作り、contextMenuEvent をオーバーライド

  • 方法2: setContextMenuPolicy(Qt.CustomContextMenu)

 customContextMenuRequested シグナルに右クリック時のイベントを実装

メニューの生成には、QMenu が使えます。
QWebEngineView での例は少ないかもしれませんが、
このメニューのカスタマイズ方法は他のQtのウィジェットでも共通なので、
「コンテキストメニュー」を併せて検索すると、サンプルは見つかるはずです。

注意点: オリジナルの挙動は、右クリックが画像やリンクの上だった場合、
追加で幾つかのメニュー項目を付け足しています。C++ソースの該当箇所


2つ目は現状何もいじらず、追加しただけの状態のWebBrowserの検索をより高速化できる方法はあるのか?という疑問です

これは、どういった意図の質問でしょうか

  • 検索アルゴリズムを改善したい → サービス提供側の領域です。

 検索オプションの工夫で出来ることはあるかもしれませんが、
ブラウザ側で対応出来るようなことはあまりないはずです。
検索制度を高める → 不要な情報が減る → 目的の情報へ辿り着く迄の時間の短縮

  • 通信や検索結果描画の処理時間を改善したい → ライブラリ側の領域です。

 HTTP/3 QUIC 対応があれば、通信プロトコルの改善は見込めるかもしれません、
処理速度に影響がありそうなのはプロセスモデルの変更位。

  • ショートカットキー等により、ユーザ操作の手間を改善したい

 例えば、chrome では、「/」「Ctrl+E」「Ctrl+K」で
直ぐに検索語を入力できる状態になります。

投稿2021/05/30 05:55

編集2021/05/31 13:59
teamikl

総合スコア8760

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/05/30 10:23

なるほど..丁寧な回答ありがとうございます Context Menuについて質問をしたいのですが 私プログラム初心者のため、Web上の記事を見て試してみてもイマイチ理解できず.. 例として、リンクをコピーする というContext Menuのサンプルのような 例として見習えるコードを頂くことは可能でしょうか... お手数おかけして申し訳ないのですが、もしお時間あるようでしたらお願いします...すいません..
teamikl

2021/05/30 11:52

回答欄に書いた通りですけど、具体的にどの部分で躓いていますか? - コードのどの部分に書いていいか解らない  → 回答に書いた方法1 方法2 の用語をヒントに検索して見て下さい - メニューの生成方法が解らない → QMenu - メニュー選択時のアクション → QAction - リンクのコピーの仕方(URL情報の所得、クリップボード操作)  → ​「C++ソースの該当箇所」が実際のコード Webの記事より詳しく書くことは(量的に)出来ないので、 解らない部分を具体的に詰めていった方が良いですよ
退会済みユーザー

退会済みユーザー

2021/05/31 12:05

なるほど..そうですねあまり漠然としすぎましたね... Context Menuについては自分で色々と調べて弄くり回してみます! メニューの日本語化については、あまり英語に詳しくなくプログラムも コピペメインでやっていたもので理解が追いついていなくて... メニューの翻訳をする際は QTranslator qtTranslator; qtTranslator.load(QLocale::system(), QStringLiteral("qtbase_")); app.installTranslator(&qtTranslator); このコードを私のコードの ``` app = QApplication(sys.argv) win = QMainWindow() view = MyWebEngineView(win) app.setApplicationName("BASIC BROWSER") app.setWindowIcon(QIcon('icon.ico')) window = MainWindow() app.exec_() ``` に含めれば良いということですかね?
teamikl

2021/05/31 13:38

それは、C++ のコードなので、 Python のコードに翻訳する必要がありますね。 加えて、翻訳リソースファイルも自分で準備する必要があります。 コード部分は、(コメント内なのでインデントに全角スペースを利用) translator = PyQt5.QtCore.QTranslator() if translator.load("翻訳リソースのファイル名"):   app.installTranslator(translator) 日本語化リソースの作成方法については、 一番最初のリンクですが、作業の流れだけ触れておくと - 2番目のリンクのメニューのソースから、翻訳する文字の抽出 → ts ファイル  ※ PyQt5 に付属の pylupdate5 は python のソースが走査対象なので、   ここは工夫が必要な点 - 翻訳文字を編集し、リソースファイル生成 → qm ファイル この作業には、コマンドライン(lreleaseコマンド)で処理する方法と、 ツール(QtLinguist)を使う方法がありますが、 どちらもPyQt5 だけでなく Qt(C++) の環境構築も必要かもしれません。 (PyQt5 に含まれてるのかどうか調べてみないと確証なし) ここは、もう少し出せる情報があります。
teamikl

2021/05/31 13:50

PyQt5アプリケーションの国際語化対応 https://doc.bccnsoft.com/docs/PyQt5/i18n.html (詳細な情報は書かれてないので、詳細はC++版の回答の最初のリンクを参照) 翻訳リソース作成に必要な ts ファイルはXML ファイルなので、 テキストエディタで作成できるのですが > uses Qt’s lrelease utility to convert the .ts files to .qm files とあるので、ts -> qm 変換に必要なプログラムの為に、 Qt をインストールする必要があるかもしれません。 私の手元のPyQt5環境にはありませんでした。
退会済みユーザー

退会済みユーザー

2021/06/01 11:30

なるほど!何度も丁寧にありがとうございます! 最後に、デフォルトのContext Menuなんですけど デフォルトのContext Menuが何個か動かないものがあって (例えばページのソース表示やダウンロードなど) これらは個別に設定しなければいけないのですかね?
teamikl

2021/06/02 00:58 編集

Context Menu は機能の呼び出しだけなので、 実際の挙動は自分で実装する必要があります。 Context Menu 一覧 https://doc.qt.io/qt-5/qwebenginepage.html#WebAction-enum - ダウンロード Requires a slot for downloadRequested().  QWebEngineProfile のシグナルで通知されるのみ。  https://doc.qt.io/qt-5/qwebengineprofile.html#downloadRequested  download item オブジェクトが渡るので、item.accept() でダウンロード開始  デフォルトの挙動はなにもしないでキャンセル - ソース表示 Requires implementation of createWindow()  QWebEnginePage のサブクラスを作り、createWindow メソッドを実装 サンプルコードと説明 (言語はC++) https://doc.qt.io/qt-5/qtwebengine-webenginewidgets-simplebrowser-example.html
teamikl

2021/06/02 02:48 編集

# ダウンロードを開始するシグナル&スロットの設定 # 保存先ダイアログを出したい場合等は、自分で実装する必要があるので # lambda~ の所に呼び出される関数を登録します browser.page().profile().downloadRequested.connect(lambda item: item.accept()) # ページのソース表示。view-source: を付けるとソース表示 browser.setUrl(QUrl("view-source:https://www.google.com/")) # Context Menu の ViewSource で # 新しいウィンドウや新規タブを開いたりするのは、 # サブクラス化して createWindow メソッドを実装してください
退会済みユーザー

退会済みユーザー

2021/06/02 07:53

なるほど丁寧にありがとうございました!あとは自分で色々やってみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問