如何使用 intersphinx 正确链接到 PyQt5 文档?
Posted
技术标签:
【中文标题】如何使用 intersphinx 正确链接到 PyQt5 文档?【英文标题】:How to properly link to PyQt5 documentation using intersphinx? 【发布时间】:2017-11-03 18:06:23 【问题描述】:我在尝试使用 intersphinx
链接到 PyQt5 docs 时遇到了一些麻烦。
尝试交叉引用任何QtCore
类(例如QThread
)不会像我预期的那样工作。我已经使用python -m sphinx.ext.intersphinx objects.inv
解析了objects.inv
可用的here,这导致了gist 中显示的输出。
不幸的是,在 python 命名空间下没有类,只有几个函数。与PyQt5
相关的所有内容都在sip:class
命名空间中。尝试使用标准 :py:class:
语法在文档中引用它不会链接到任何东西(因为 sphinx 没有看到该引用连接到任何东西),并且使用 :sip:class:
会导致 Unknown interpreted text role "sip:class"
的警告,这是有道理的,因为不是已知的参考代码。
那么,我们如何通过 intersphinx 访问 PyQt 的文档(如果可以的话)?
【问题讨论】:
我认为这是不可能的。看看riverbankcomputing.com/pipermail/pyqt/2013-March/032528.html,他们提到了可以引用的类的有限包含。 好吧,没有什么是不可能的。这是向项目提交 PR 的问题。在***.com/a/45700546/2214933 上查看我对类似问题的回答 【参考方案1】:编辑: 我用这个解决方案创建 python 包:https://pypi.org/project/sphinx-qt-documentation/
原始答案:
我使用另一种方法来解决这个问题。我创建了自定义 sphinx 插件来翻译动态库存文件以使用 sip
域。它允许选择应该指向哪些文档(请参阅顶部的文档字符串)。它适用于我的项目,但我不确定它是否支持所有情况。
这个扩展需要sphinx.ext.intersphinx
扩展在sphinx扩展中配置,PyQt
在映射中配置
intersphinx_mapping = ...,
"PyQt": ("https://www.riverbankcomputing.com/static/Docs/PyQt5", None)
"""
This module contains sphinx extension supporting for build PartSeg documentation.
this extensio provides one configuration option:
`qt_documentation` with possibe values:
* PyQt - linking to PyQt documentation on https://www.riverbankcomputing.com/static/Docs/PyQt5/api/ (incomplete)
* Qt - linking to Qt documentation on "https://doc.qt.io/qt-5/" (default)
* PySide - linking to PySide documentation on "https://doc.qt.io/qtforpython/PySide2/"
"""
import re
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment
from docutils.nodes import Element, TextElement
from docutils import nodes
from typing import List, Optional, Dict, Any
from sphinx.locale import _
from sphinx.ext.intersphinx import InventoryAdapter
try:
from qtpy import QT_VERSION
except ImportError:
QT_VERSION = None
# TODO add response to
# https://***.com/questions/47102004/how-to-properly-link-to-pyqt5-documentation-using-intersphinx
signal_slot_uri =
"Qt": "https://doc.qt.io/qt-5/signalsandslots.html",
"PySide": "https://doc.qt.io/qtforpython/overviews/signalsandslots.html",
"PyQt": "https://www.riverbankcomputing.com/static/Docs/PyQt5/signals_slots.html"
signal_name =
"Qt": "Signal",
"PySide": "Signal",
"PyQt": "pyqtSignal"
slot_name =
"Qt": "Slot",
"PySide": "Slot",
"PyQt": "pyqtSlot"
signal_pattern = re.compile(r'((\w+\d?\.QtCore\.)|(QtCore\.)|(\.)())?(pyqt)?Signal')
slot_pattern = re.compile(r'((\w+\d?\.QtCore\.)|(QtCore\.)|(\.)())?(pyqt)?Slot')
def missing_reference(app: Sphinx, env: BuildEnvironment, node: Element, contnode: TextElement
) -> Optional[nodes.reference]:
"""Linking to Qt documentation."""
target: str = node['reftarget']
inventories = InventoryAdapter(env)
objtypes = None # type: Optional[List[str]]
if node['reftype'] == 'any':
# we search anything!
objtypes = ['%s:%s' % (domain.name, objtype)
for domain in env.domains.values()
for objtype in domain.object_types]
domain = None
else:
domain = node.get('refdomain')
if not domain:
# only objects in domains are in the inventory
return None
objtypes = env.get_domain(domain).objtypes_for_role(node['reftype'])
if not objtypes:
return None
objtypes = ['%s:%s' % (domain, objtype) for objtype in objtypes]
if target.startswith("PySide2"):
head, tail = target.split(".", 1)
target = "PyQt5." + tail
obj_type_name = "sip:".format(node.get("reftype"))
if obj_type_name not in inventories.named_inventory["PyQt"]:
return None
target_list = [target, "PyQt5." + target]
target_list += [name + "." + target for name in inventories.named_inventory["PyQt"]["sip:module"].keys()]
if signal_pattern.match(target):
uri = signal_slot_uri[app.config.qt_documentation]
dispname = signal_name[app.config.qt_documentation]
version = QT_VERSION
elif slot_pattern.match(target):
uri = signal_slot_uri[app.config.qt_documentation]
dispname = slot_name[app.config.qt_documentation]
version = QT_VERSION
else:
for target_name in target_list:
if target_name in inventories.main_inventory[obj_type_name]:
proj, version, uri, dispname = inventories.named_inventory["PyQt"][obj_type_name][target_name]
print(node) # print nodes with unresolved references
break
else:
return None
if app.config.qt_documentation == "Qt":
html_name = uri.split("/")[-1]
uri = "https://doc.qt.io/qt-5/" + html_name
elif app.config.qt_documentation == "PySide":
html_name = "/".join(target.split(".")[1:]) + ".html"
uri = "https://doc.qt.io/qtforpython/PySide2/" + html_name
# remove this line if you would like straight to pyqt documentation
if version:
reftitle = _('(in %s v%s)') % (app.config.qt_documentation, version)
else:
reftitle = _('(in %s)') % (app.config.qt_documentation,)
newnode = nodes.reference('', '', internal=False, refuri=uri, reftitle=reftitle)
if node.get('refexplicit'):
# use whatever title was given
newnode.append(contnode)
else:
# else use the given display name (used for :ref:)
newnode.append(contnode.__class__(dispname, dispname))
return newnode
def setup(app: Sphinx) -> Dict[str, Any]:
app.connect('missing-reference', missing_reference)
app.add_config_value('qt_documentation', "Qt", True)
return
'version': "0.9",
'env_version': 1,
'parallel_read_safe': True
【讨论】:
这作为一个独立的 sphinx 扩展非常棒。您是否考虑过将其与您使用它的项目分开发布? 欢迎您pypi.org/project/sphinx-qt-documentation 太棒了。非常感谢!【参考方案2】:为了让intersphinx
映射适用于我使用 PyQt5 的项目,我执行了以下操作:
-
下载原objects.inv文件
将
:sip:
域更改为:py:
重定向大多数 PyQt 对象的 URL 以指向 Qt 网站,这意味着当有人单击我的文档中的 QWidget
时,他们不会被定向到 PyQt-QWidget,而是被定向到 Qt-QWidget
添加别名以便:class:`QWidget`
、:class:`QtWidgets.QWidget`
和:class:`PyQt5.QtWidgets.QWidget`
都链接到Qt-QWidget
如果你想在你自己的项目中使用我修改过的objects.inv
文件,你可以download它,将它保存到与conf.py
文件相同的目录,然后在你的intersphinx_mapping
字典中编辑@987654338 @成为
intersphinx_mapping =
# 'PyQt5': ('http://pyqt.sourceforge.net/Docs/PyQt5/', None),
'PyQt5': ('', 'pyqt5-modified-objects.inv'),
如果我的'pyqt5-modified-objects.inv'
文件不符合你项目的要求(例如我没有为所有Qt模块添加别名,只有QtWidgets
、QtCore
和QtCore
和QtGui
)那么你可以修改@ 987654326@ 自动执行上述步骤 1 - 4。
源代码也可以用来为PyQt4创建修改后的objects.inv
文件;但是,PyQt4 的原始 objects.inv
文件不包含所有 Qt 模块和类的完整列表,因此使用 PyQt4 的 intersphinx
映射不是很有用。
注意:SourceForge 团队目前正在解决一些issues,因此执行源代码将引发ConnectionError
,直到他们的问题得到解决。
【讨论】:
以上是关于如何使用 intersphinx 正确链接到 PyQt5 文档?的主要内容,如果未能解决你的问题,请参考以下文章
如何正确使用.kv文件和.py? - 从 .kv 调用函数如何构建 .py