Open peterfpeterson opened 4 months ago
QtWebView
As per Pete's request, I will be do a brief overview of qtwebview
to showcase its features, it's limitations, and give an example of a very basic implementation within another software package called SNAPRed.
Here is a link to the qtwebview doc page for Qt version 5.15.xx
:
https://doc.qt.io/qt-5/qtwebview-index.html
Qtwebview is also supported within Qt version 6.7.x
and here is a link to that documentation page:
https://doc.qt.io/qt-6/qtwebview-index.html
Addition of PyQtWebEngine
within the conda environment:
- pyqtwebengine
QtWebView
is a component within the Qt framework that enables the display of web content within QML applications. This viewer is lightweight and has no requirement of a complete web browser setup. QtWebView can be employed using either local built html files or web based URL addresses. Found at this ink is an overview of all the members available.
Two particularly notable methods include:
runJavaScript(string script, variant callback)
loadHtml(string html, url baseUrl)
Note: WebView does not support loading content through the Qt Resource System.
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QHBoxLayout, QPushButton, QWidget
from snapred.meta.Config import Config
class UserDocsButton(QWidget):
def __init__(self, parent=None):
super(UserDocsButton, self).__init__(parent)
self.setStyleSheet("background-color: #F5E9E2;")
self.initUI()
def initUI(self):
# Layout setup
layout = QHBoxLayout(self)
self.setLayout(layout)
# Button to launch the web view
self.button = QPushButton("User Documentation", self)
self.button.setStyleSheet("background-color: #F5E9E2;")
self.button.clicked.connect(self.launchWebView)
layout.addWidget(self.button)
def launchWebView(self):
# Create and configure the web view
self.webView = QWebEngineView()
self.webView.setWindowTitle("Documentation")
self.webView.resize(800, 600)
# Point to the specific file on the filesystem
url = QUrl.fromLocalFile(str(Config["docs.user.path"]))
self.webView.setUrl(url)
# Show the web view
self.webView.show()
In the example above a widget is implemented within the PyQt
framework to enable the users to access the documentation through the UI. This script defines a simple button and connects it to a method which launches an instance of QWebEngineView
with a specified target pointing to a local system html file. Loading from a web based URL would be very similar and should be as simple as changing a single line.
Additional UI features for the web viewer can be added.
QtWebEngine needs to get imported before the QApplication is created. This will have to happen in the startup code for workbench. To see the error
from qtpy import QtWidgets, QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts)
app = QtWidgets.QApplication([''])
from qtpy.QtWebEngineWidgets import QtWebChannel, QWebEngineView
reversing the order of the last two lines fixes the issue.
Here is a prototype for this implementation. Please look at the attached files. There is still some work to be done to find the solution between good rendering of the equations and retaining the layout of the doc pages.
import sys
import os
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QPushButton
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor
from http.server import SimpleHTTPRequestHandler, HTTPServer
import threading
class MyRequestInterceptor(QWebEngineUrlRequestInterceptor):
def interceptRequest(self, info):
url = info.requestUrl()
if url.host() == "cdn.jsdelivr.net":
info.setHttpHeader(b"Access-Control-Allow-Origin", b"*")
class HelpWindow(QWidget):
def __init__(self, rootDir, parent=None):
super().__init__(parent)
self.setWindowTitle('Mantid Help Window')
self.setGeometry(300, 100, 1200, 800)
# Assuming the HTML files are directly in the rootDir
self.convertDiffcalPath = "http://localhost:8000/ConvertDiffCal.html"
self.anotherPagePath = "http://localhost:8000/EstimateResolutionDiffraction.html"
layout = QVBoxLayout(self)
self.webView = QWebEngineView()
# Create and set the request interceptor
interceptor = MyRequestInterceptor()
self.webView.page().profile().setUrlRequestInterceptor(interceptor)
layout.addWidget(self.webView)
self.toggleButton = QPushButton('Go to another page')
self.toggleButton.clicked.connect(self.togglePage)
layout.addWidget(self.toggleButton)
self.currentPage = 'convertDiffcal'
self.loadPage(self.convertDiffcalPath)
def loadPage(self, url):
self.webView.setUrl(QUrl(url))
def togglePage(self):
if self.currentPage == 'convertDiffcal':
self.loadPage(self.anotherPagePath)
self.currentPage = 'anotherPage'
self.toggleButton.setText('Go back to first page')
else:
self.loadPage(self.convertDiffcalPath)
self.currentPage = 'convertDiffcal'
self.toggleButton.setText('Go to another page')
def startLocalServer(rootDir):
os.chdir(rootDir)
handler = SimpleHTTPRequestHandler
httpd = HTTPServer(('localhost', 8000), handler)
httpd.serve_forever()
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Usage: python script.py /path/to/docs/html/")
sys.exit(1)
ROOT_DIR = sys.argv[1]
# Start the local server in a separate thread
serverThread = threading.Thread(target=startLocalServer, args=(ROOT_DIR,), daemon=True)
serverThread.start()
app = QApplication(sys.argv)
# Launch the Help Window
mainWin = HelpWindow(ROOT_DIR)
mainWin.show()
sys.exit(app.exec_())
boost::python 1.84 docs for calling python functions and methods
The current mantid help system uses qtassistant to show the help documentation. This method of including the docs is always in agreement with the code. However, there are some problems with this approach:
Describe the solution you'd like
Describe alternatives you've considered
qtwebview might be able to do it
Additional context