如何使用Python开发WOX插件?
#教程 #python #plugin #wox

Representative image for plugin

阅读有关Medium的本文。

Wox是Windows平台的全功能发射器。它类似于Mac’s Spotlight,可以通过大量的plugins进行增强。

我已经使用了Wox(与全能的Everything插件一起使用)已有几年了,并且喜欢它。但是,我一直对工作英语词典插件的不可用,该插件也将离线工作。因此,我开始为自己开发一个插件,但由于缺乏同样的文档而感到沮丧。

在下面,我分享了我如何使用Python开发词典插件(简单词典)。我希望这将帮助您寻求开发另一个基于Python的插件。可以从官方的Wox plugin website中安装Easy Dictionary。源代码可在GitHub上找到。请检查一下,您了解为什么我将其命名为简单的字典。

Easy Dictionary Usage Screenshot

好吧,我们要做的就是在下面的简单步骤下遵循。


我们需要创建一个Python文件以包含我们的代码。让我们称其为main.py(文件名可能是任何东西)。添加一个从wox.Wox继承的类(类名),并实现与以下方式相同的:

# Only for type-hinting in Python
# For more info: https://docs.python.org/3/library/typing.html
from typing import Dict, List

# No need to worry about the presence of the `Wox` class. Wox runtime has its own 
# python environment that contains the required `Wox` class
from wox import Wox


# Class name could be anything
# NOTE: Don't forget to inherit from `Wox`
class EDict(Wox):
    # Overriding the `__init__` is NOT mandatory
    def __init__(self, *args, **kwargs) -> None:
        """Initializer for `EDict` class"""
        # Add all the custom initialization required for the `EDict` class

        # NOTE: If overriding the `__init__` method, make sure to call the
        # parent class initializer like below
        super().__init__(*args, **kwargs)

    # NOTE: We must override the `query` method
    # `query` method is called when a user queries the plugin using its trigger
    # keyword in Wox. Wox passes the user input as an argument
    def query(self, key: str) -> List[Dict[str, str]]:
        results: List[Dict[str, str]] = []
        # NOTE: Each item on the list must be a dictionary that should contain 
        # at least following keys. For more info, check out the annotated screenshot below
            # "Title": Main search result to show in Wox
            # "IcoPath": Path of image/icon for the search result in Wox
            # "SubTitle": Subtitle of the search result in Wox

        # Our core logic goes here or in any other method that we can call here

        return results


if __name__ == "__main__":
    # NOTE: Don't forget to instantiate the above class
    # No need to return anything
    EDict()

我们需要创建另一个名为plugin.json的文件(名称必须相同)。 WOX寻找此JSON文件以获取有关插件的详细信息,并在运行时实例化。 plugin.json文件下方是用于简单字典插件的。

plugin.json文件需要以下详细信息:

  • id :这必须是我们在线生成或使用任何编程语言的UUID。它应该与Wox可用的任何其他插件的ID相冲突。
  • ActionKeyword :使用WOX时,它是插件的触发关键字。请参阅下面的屏幕截图,显示轻松的字典在打字时触发。

Easy Dictionary Usage Screenshot with markings to highlight different components

  • 名称,描述,作者,版本:这些是自称的。
  • 语言:Wox支持以许多语言编写插件,因为通信基于RPC。因此,语言不是WOX插件的障碍。在这里,我们需要指定我们编写插件的语言(在这种情况下为Python)。
  • 网站:这可以是空字符串,也可以链接到插件的网站。
  • icopath :我们希望在插件中使用的图像/图标路径。此图像/图标必须是插件软件包的一部分(我们将很快包装插件)。
  • executeFilename :它指定了我们插件的入口点。请注意,这是我们之前创建的相同的main.py文件。
{
    "ID":"0c6569f79d49409e8e5e42e1ec8bb035",
    "ActionKeyword":"ed",
    "Name":"Easy Dictionary",
    "Description":"Provides an offline English Dictionary",
    "Author":"ashutosh",
    "Version":"2.2.0",
    "Language":"python",
    "Website":"https://github.com/ashu-tosh-kumar/Wox.Plugin.eDict",
    "IcoPath": "icons\\edict.png",
    "ExecuteFileName":"main.py"
  }

我们快要完成了。接下来,我们只需抓住带有files edict.png(在plugin.json中使用)和edit.ico的文件main.pyplugin.jsonplugin.jsonicons的文件夹,并将它们一起将它们划入Wox.Plugin.<plugin_name>.zip中。在我们的情况下,它是Wox.Plugin.eDict.zip

一旦拉链,就将邮政编码手动更改为.wox。因此,最后我们将拥有zupperiped文件:Wox.Plugin.eDict.wox

可以将文件Wox.Plugin.eDict.wox拖放到Wox发射器上以手动安装它。或者,我们可以在Wox的官方网站上分享它,以通过创建帐户和上传上述文件来更广泛使用。

就是这样。按照上述步骤操作,您可以使用我们旧的Chap Python语言创建自己的Wox插件。为了完整,让我们仔细阅读以下简易字典的实际代码。


首先,让我们看看我们需要包装的简单字典所需的文件。请在GitHub上查看源代码。

|-icons  # Folder
| |-edict.ico
| |-edict.png
|-dictionary_compact_with_words.zip
|-main.py
|-plugin.json
|-spell.py
  • 图标:图标文件夹包含项目中使用的图像edict.png和图标edict.ico
  • dictionary_compact_with_words.zip :它包含JSON格式的未删节的Webster字典。我们将其拉开以减小插件尺寸。我们将其解压缩以在__init__EDict中用于python。
class EDict(Wox):
    """Easy Dictionary Class used by Wox"""

    def __init__(self, *args, **kwargs) -> None:
        """Initializer for `EDict` class"""
        # Unzipping the dictionary for usage
        with ZipFile(DICTIONARY_ZIP_FILE, "r") as zip_file:
            with zip_file.open(DICTIONARY_JSON_FILE) as edict_file:
                self._edict = load(edict_file)

        # Key "cb2b20da-9168-4e8e-8e8f-9b54e7d42214" gives a list of all words
        # For more info, checkout: https://github.com/matthewreagan/WebstersEnglishDictionary
        words = self._edict["cb2b20da-9168-4e8e-8e8f-9b54e7d42214"]
        self._spell_correct = SpellCorrect(words)

        super().__init__(*args, **kwargs)
  • main.py :这是我们插件的起点。我们覆盖了EDict中的query方法,以为用户查询提供结果。如前所述,我们使用方法_Format_Result将每个结果格式化为词典。由于使用了基本词典,因此在_format_result中的某些格式规则已适当。此外,如果我们找不到用户输入密钥的定义,我们将尝试自动校正单词并显示自动校正单词的结果。
def query(self, key: str) -> List[Dict[str, str]]:
    """Overrides Wox query function to capture user input

    Args:
        key (str): User search input

    Returns:
        List[Dict[str, str]]: Returns list of results where each result is a dictionary
    """
    results: List[Dict[str, str]] = []
    key = key.strip().lower()

    if not key:
        # Avoid looking for empty key
        return results

    try:
        # Look for the given key
        definitions = self._edict[key]

        # Format results in the form of a dictionary
        results = self._format_result(definitions, key, MAXIMUM_RESULTS, False)
    except KeyError:
        # Try correcting the key and looking again with the corrected key
        # This is an additional feature where we try to auto-correct the user input
        # This helps in case of spelling mistakes
        try:
            corrected_key = self._spell_correct.correction(key)
            definitions = self._edict[corrected_key]
            results = self._format_result(definitions, corrected_key, MAXIMUM_RESULTS, True)
        except KeyError:
            # Word doesn't exist in our dictionary
            pass

    return results
  • plugin.json :已解释。
  • spell.py :简单地实现了基于概率的方法来自动校正单词。实施取自norvig.com。此文件由main.py
  • 使用