def __init__(self, parent=None): QWidget.__init__(self, parent) self.l = l = QVBoxLayout(self) self.view = v = QWebEngineView(self) v.loadStarted.connect(self.load_started) v.loadProgress.connect(self.load_progress) v.loadFinished.connect(self.load_finished) l.addWidget(v) self.h = h = QHBoxLayout() l.addLayout(h) self.download_progress = d = DownloadProgress(self) h.addWidget(d) self.home_button = b = QPushButton(_('Home')) b.clicked.connect(self.home) h.addWidget(b) self.back_button = b = QPushButton(_('Back')) b.clicked.connect(v.back) h.addWidget(b) self.forward_button = b = QPushButton(_('Forward')) b.clicked.connect(v.forward) h.addWidget(b) self.progress_bar = b = QProgressBar(self) h.addWidget(b) self.reload_button = b = QPushButton(_('Reload')) b.clicked.connect(v.reload) h.addWidget(b)
def event(self, event): if event.type() == QEvent.Type.ChildPolished: child = event.child() if 'HostView' in child.metaObject().className(): self._host_widget = child self._host_widget.setFocus(Qt.FocusReason.OtherFocusReason) return QWebEngineView.event(self, event)
class Inspector(QWidget): def __init__(self, dock_action, parent=None): QWidget.__init__(self, parent=parent) self.view_to_debug = parent self.view = None self.layout = QHBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.dock_action = dock_action QTimer.singleShot(0, self.connect_to_dock) def connect_to_dock(self): ac = self.dock_action ac.toggled.connect(self.visibility_changed) if ac.isChecked(): self.visibility_changed(True) def visibility_changed(self, visible): if visible and self.view is None: self.view = QWebEngineView(self.view_to_debug) self.view_to_debug.page().setDevToolsPage(self.view.page()) self.layout.addWidget(self.view) def sizeHint(self): return QSize(600, 1200)
def show_devtools(self): if not hasattr(self, '_devtools_page'): self._devtools_page = QWebEnginePage() self._devtools_view = QWebEngineView(self) self._devtools_view.setPage(self._devtools_page) self._page.setDevToolsPage(self._devtools_page) self._devtools_dialog = d = QDialog(self) d.setWindowTitle('Inspect Lookup page') v = QVBoxLayout(d) v.addWidget(self._devtools_view) d.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Close) d.bb.rejected.connect(d.reject) v.addWidget(d.bb) d.resize(QSize(800, 600)) d.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, False) self._devtools_dialog.show() self._page.triggerAction(QWebEnginePage.WebAction.InspectElement)
def main(url): # This function is run in a separate process and can do anything it likes, # including use QWebEngine. Here it simply opens the passed in URL # in a QWebEngineView app = Application([]) w = QWebEngineView() w.setUrl(QUrl(url)) w.show() w.raise_() app.exec_()
def __init__(self, parent=None): QWebEngineView.__init__(self, parent) self._last_reload_at = None self.renderProcessTerminated.connect(self.render_process_terminated) self.render_process_restarted.connect(self.reload, type=Qt.ConnectionType.QueuedConnection)
prints(self.webengine_crash_message) if self._last_reload_at is not None and monotonic() - self._last_reload_at < 2: self.render_process_failed.emit() prints('The Qt WebEngine Render process crashed too often') else: self._last_reload_at = monotonic() self.render_process_restarted.emit() prints('Restarting Qt WebEngine') if __name__ == '__main__': from calibre.gui2 import Application from calibre.gui2.tweak_book.preview import WebPage from qt.core import QMainWindow app = Application([]) view = QWebEngineView() page = WebPage(view) view.setPage(page) w = QMainWindow() w.setCentralWidget(view) class Test(Bridge): s1 = from_js(object) j1 = to_js() t = Test(view.page()) t.s1.connect(print) w.show() view.setHtml(''' <p>hello</p> ''') app.exec()
def visibility_changed(self, visible): if visible and self.view is None: self.view = QWebEngineView(self.view_to_debug) self.view_to_debug.page().setDevToolsPage(self.view.page()) self.layout.addWidget(self.view)
def __init__(self, parent, prefs): QWebEngineView.__init__(self, parent) self._page = Page(prefs) self._page.elem_clicked.connect(self.elem_clicked) self._page.frag_shown.connect(self.frag_shown) self.setPage(self._page)
class Lookup(QWidget): def __init__(self, parent): QWidget.__init__(self, parent) self.is_visible = False self.selected_text = '' self.current_query = '' self.current_source = '' self.l = l = QVBoxLayout(self) self.h = h = QHBoxLayout() l.addLayout(h) self.debounce_timer = t = QTimer(self) t.setInterval(150), t.timeout.connect(self.update_query) self.source_box = sb = QComboBox(self) self.label = la = QLabel(_('Lookup &in:')) h.addWidget(la), h.addWidget(sb), la.setBuddy(sb) self.view = View(self) self.view.inspect_element.connect(self.show_devtools) self._page = Page(create_profile(), self.view) apply_font_settings(self._page) secure_webengine(self._page, for_viewer=True) self.view.setPage(self._page) l.addWidget(self.view) self.populate_sources() self.source_box.currentIndexChanged.connect(self.source_changed) self.view.setHtml('<p>' + _('Double click on a word in the book\'s text' ' to look it up.')) self.add_button = b = QPushButton(QIcon(I('plus.png')), _('Add sources')) b.setToolTip(_('Add more sources at which to lookup words')) b.clicked.connect(self.add_sources) self.refresh_button = rb = QPushButton(QIcon(I('view-refresh.png')), _('Refresh')) rb.setToolTip( _('Refresh the result to match the currently selected text')) rb.clicked.connect(self.update_query) h = QHBoxLayout() l.addLayout(h) h.addWidget(b), h.addWidget(rb) self.auto_update_query = a = QCheckBox(_('Update on selection change'), self) a.setToolTip( textwrap.fill( _('Automatically update the displayed result when selected text in the book changes. With this disabled' ' the lookup is changed only when clicking the Refresh button.' ))) a.setChecked(vprefs['auto_update_lookup']) a.stateChanged.connect(self.auto_update_state_changed) l.addWidget(a) self.update_refresh_button_status() def auto_update_state_changed(self, state): vprefs['auto_update_lookup'] = self.auto_update_query.isChecked() self.update_refresh_button_status() def show_devtools(self): if not hasattr(self, '_devtools_page'): self._devtools_page = QWebEnginePage() self._devtools_view = QWebEngineView(self) self._devtools_view.setPage(self._devtools_page) self._page.setDevToolsPage(self._devtools_page) self._devtools_dialog = d = QDialog(self) d.setWindowTitle('Inspect Lookup page') v = QVBoxLayout(d) v.addWidget(self._devtools_view) d.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Close) d.bb.rejected.connect(d.reject) v.addWidget(d.bb) d.resize(QSize(800, 600)) d.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, False) self._devtools_dialog.show() self._page.triggerAction(QWebEnginePage.WebAction.InspectElement) def add_sources(self): if SourcesEditor(self).exec() == QDialog.DialogCode.Accepted: self.populate_sources() self.source_box.setCurrentIndex(0) self.update_query() def source_changed(self): s = self.source if s is not None: vprefs['lookup_location'] = s['name'] self.update_query() def populate_sources(self): sb = self.source_box sb.clear() sb.blockSignals(True) for item in vprefs['lookup_locations']: sb.addItem(item['name'], item) idx = sb.findText(vprefs['lookup_location'], Qt.MatchFlag.MatchExactly) if idx > -1: sb.setCurrentIndex(idx) sb.blockSignals(False) def visibility_changed(self, is_visible): self.is_visible = is_visible self.update_query() @property def source(self): idx = self.source_box.currentIndex() if idx > -1: return self.source_box.itemData(idx) @property def url_template(self): idx = self.source_box.currentIndex() if idx > -1: return self.source_box.itemData(idx)['url'] @property def query_is_up_to_date(self): query = self.selected_text or self.current_query return self.current_query == query and self.current_source == self.url_template def update_refresh_button_status(self): b = self.refresh_button b.setVisible(not self.auto_update_query.isChecked()) b.setEnabled(not self.query_is_up_to_date) def update_query(self): self.debounce_timer.stop() query = self.selected_text or self.current_query if self.query_is_up_to_date: return if not self.is_visible or not query: return self.current_source = self.url_template url = self.current_source.format(word=query) self.view.load(QUrl(url)) self.current_query = query self.update_refresh_button_status() def selected_text_changed(self, text, annot_id): already_has_text = bool(self.current_query) self.selected_text = text or '' if self.auto_update_query.isChecked() or not already_has_text: self.debounce_timer.start() self.update_refresh_button_status() def on_forced_show(self): self.update_query()