99 lines
4.2 KiB
Plaintext
99 lines
4.2 KiB
Plaintext
Porting add-ons to Anki 2.1
|
|
---------------------------
|
|
|
|
Python 3
|
|
---------
|
|
|
|
Anki 2.1 requires Python 3.5 or later. After installing Python 3 on your
|
|
machine, you can use the 2to3 tool to automatically convert your existing
|
|
scripts to Python 3 code on a folder by folder basis, like:
|
|
|
|
2to3-3.5 --output-dir=aqt3 -W -n aqt
|
|
mv aqt aqt-old
|
|
mv aqt3 aqt
|
|
|
|
Most simple code can be converted automatically, but there may be parts of the
|
|
code that you need to manually modify.
|
|
|
|
Qt5 / PyQt5
|
|
------------
|
|
|
|
The syntax for connecting signals and slots has changed in PyQt5. Recent PyQt4
|
|
versions support the new syntax as well, so after updating your add-ons you
|
|
may find they still work in Anki 2.0.x as well.
|
|
|
|
More info is available at
|
|
http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html
|
|
|
|
One add-on author reported that the following tool was useful to automatically
|
|
convert the code:
|
|
https://github.com/rferrazz/pyqt4topyqt5
|
|
|
|
Compatibility with Anki 2.0
|
|
----------------------------
|
|
|
|
It should be possible for many add-ons to support both Anki 2.0 and 2.1 at the
|
|
same time.
|
|
|
|
Most Python 3 code will run on Python 2 as well, though extra work may be
|
|
required when dealing with file access and byte strings.
|
|
|
|
The Qt modules are in 'PyQt5' instead of 'PyQt4'. You can do a conditional
|
|
import, but an easier way is to import from aqt.qt - eg "from aqt.qt import *"
|
|
|
|
The most difficult part is the change from the unsupported QtWebKit to
|
|
QtWebEngine. If you do any non-trivial work with webviews, some work will be
|
|
required to port your code to Anki 2.1, as described in the next section.
|
|
|
|
If you find that non-trivial changes are required to get your add-on working
|
|
with Anki 2.1, the easiest option is to drop support for older Anki versions.
|
|
Please see the 'sharing updated add-ons' section below for more information.
|
|
|
|
Webview changes
|
|
----------------
|
|
|
|
Qt 5 has dropped WebKit in favour of the Chromium-based WebEngine, so
|
|
Anki's webviews are now using WebEngine. Of note:
|
|
|
|
- You can now debug the webviews using an external Chrome instance, by setting
|
|
the env var QTWEBENGINE_REMOTE_DEBUGGING to 8080 prior to starting Anki,
|
|
then surfing to localhost:8080 in Chrome.
|
|
- WebEngine uses a different method of communicating back to Python.
|
|
AnkiWebView() is a wrapper for webviews which provides a pycmd(str) function in
|
|
Javascript which will call the ankiwebview's onBridgeCmd(str) method. Various
|
|
parts of Anki's UI like reviewer.py and deckbrowser.py have had to be
|
|
modified to use this.
|
|
- Javascript is evaluated asynchronously, so if you need the result of a JS
|
|
expression you can use ankiwebview's evalWithCallback().
|
|
- As a result of this asynchronous behaviour, editor.saveNow() now requires a
|
|
callback. If your add-on performs actions in the browser, you likely need to
|
|
call editor.saveNow() first and then run the rest of your code in the callback.
|
|
Calls to .onSearch() will need to be changed to .search()/.onSearchActivated()
|
|
as well. See the browser's .deleteNotes() for an example.
|
|
- Various operations that were supported by WebKit like setScrollPosition() now
|
|
need to be implemented in javascript.
|
|
- Page actions like mw.web.triggerPageAction(QWebEnginePage.Copy) are also
|
|
asynchronous, and need to be rewritten to use javascript or a delay.
|
|
- WebEngine doesn't provide a keyPressEvent() like WebKit did, so the code
|
|
that catches shortcuts not attached to a menu or button has had to be changed.
|
|
See the way reviewer.py calls setStateShortcuts() for an example.
|
|
|
|
Add-ons without a top level file
|
|
---------------------------------
|
|
|
|
Add-ons no longer require a top level file - if you just distribute a single
|
|
folder, the folder's __init__.py file will form the entry point. This will not
|
|
work in 2.0.x however.
|
|
|
|
Sharing updated add-ons
|
|
------------------------
|
|
|
|
If you've succeeded in making an add-on that supports both 2.0.x and 2.1.x at
|
|
the same time, please feel free to upload it to the shared add-ons area, and
|
|
mention in the description that it works with both versions.
|
|
|
|
If you've decided to make a separate 2.1.x version, it's probably best to just
|
|
post a link to it in your current add-on description or upload it separately.
|
|
When we get closer to a release I'll look into adding separate uploads for the
|
|
two versions.
|