软件内置帮助文档,原理是加载本地html文件,加载到QDialog中展示

帮助界面

utils中创建help_dialog.py文件,内容如下:

import os
import sys

from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtWebKitWidgets import QWebView, QWebPage
from PyQt5.QtWidgets import QDialog, QVBoxLayout


class CustomHelpDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)

def set_theme(self, theme, bg_color):
self.setStyleSheet(bg_color)

def set_title(self, title):
self.setWindowTitle(title)


class CustomWebView(QWebView):
def __init__(self, parent=None):
super().__init__(parent)
self.setStyleSheet('font-family: Microsoft YaHei')
self.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
self.page().linkClicked.connect(self.linkClicked)

def linkClicked(self, url):
QDesktopServices.openUrl(url)


def refresh_help_dialog(help_dialog, theme, name=None):
if help_dialog is None:
return
bg_color = 'background: white' if theme == 'light' else 'background: #2B2D30'
help_dialog.set_theme(theme, bg_color)
web_view: QWebView = help_dialog.layout().itemAt(0).widget()
web_view.setStyleSheet(bg_color)
if name is not None:
url = QUrl.fromLocalFile(f'{os.path.dirname(sys.argv[0])}/markdown/{name}.html')
web_view.load(url)
else:
web_view.reload()


def show_help_dialog(main, name, title):
bg_color = 'background: white' if main.theme == 'light' else 'background: #2B2D30'
if main.help_dialog is None:
main.help_dialog = CustomHelpDialog(main)
main.help_dialog.set_title(f'{title}—帮助文档')
# add a label to dialog
web_view = CustomWebView()
web_view.setStyleSheet(bg_color)
main.help_dialog.set_theme(main.theme, bg_color)
layout = QVBoxLayout()
layout.setContentsMargins(4, 34, 4, 0)
layout.addWidget(web_view)
main.help_dialog.setLayout(layout)

url = QUrl.fromLocalFile(f'{os.path.dirname(sys.argv[0])}/markdown/{name}.html')
web_view.load(url)
main.help_dialog.resize(820, 700)
else:
main.help_dialog.set_title(f'{title}—帮助文档')
# 主题由js从文件中获取,需要刷新
refresh_help_dialog(main.help_dialog, main.theme, name)

main.help_dialog.show()

按钮设计

使用Qt Designer在UI中添加帮助文档按钮,找到prev_tools_teach,内部添加QToolButton组件,并设置layoutLeftMargin设置为4,其他 Margin 设置为0,Spacing 设置为2。按钮设置如下图。

按钮绑定

preview.py文件的bind_func方法中添加绑定代码

preview.py
from utils.help_dialog import show_help_dialog
def bind_func(main):
_ui = main.ui
...
_ui.button_help.clicked.connect(lambda self: show_help_dialog(main, 'preview', '数据预览'))

文档编写

在根目录创建目录markdown,目录下存放具体的文档,格式是.html。其内容有要求,具体是从目录的them.json文件中读取主题信息,然后读取对应css样式文件,css文件放在markdown/css/目录下。

<!doctype html>
<html>
<head>
<meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'>
<title>preview</title>
<link rel="stylesheet" rev="stylesheet" id="style" type="text/css" media="all" />
<script type="text/javascript" src="theme.json"></script>
<script>
(function change_skin(){
path = 'css/' + theme + '.css'
document.getElementById("style").href=path;
})()
</script>
</head>
<body class='typora-export os-windows'>
<div class='typora-export-content'>
<div id='write' class=''><h2 id='添加栅格影像'><span>添加栅格影像</span></h2></div></div>
</body>
</html>

样式文件下载地址:

写入主题到theme.json文件中,在切换主题时写入到文件,并刷新dialog

main.py
class PyQgisSEApp(QMainWindow, Ui_MainWindow):
def __init__(self, app: QgsApplication):
...
self.help_dialog = None # 帮助Dialog
...

def switch_theme(self):
...
# 写入主题信息到文件
self.save_theme_file()
# 刷新帮助Dialog
refresh_help_dialog(self.help_dialog, self.theme)
...

def save_theme_file(self):
try:
path = f'{os.path.dirname(sys.argv[0])}/markdown/theme.json'
f = open(path, 'w', encoding='utf-8')
f.write(f"theme='{self.theme}'")
f.close()
except Exception as e:
print(e)

效果预览

效果如下: