How to add suport for pyqtlet2?

96 views
Skip to first unread message

Mauro Condarelli

unread,
May 4, 2023, 3:43:59 AM5/4/23
to PyInstaller
I am using pyqtlet2 module from PyPi (pyqtlet2 sources are available at https://github.com/JaWeilBaum/pyqtlet2).
Problem is this module is a relatively thin layer around Leaflet (https://leafletjs.com/index.html) which is a javascript lib. Pyqtlet2 uses PyQt WebEngine to render HTML page and the module includes a frozen copy of Leaflet.

Trying to use PyInstaller to package my application (or even a simple test app) fails and in the generated directories I see no trace of pyqtlet2 at all (for a small test see https://bpa.st/2EMB2).

I assume some kind of "hook" is needed, but I don't know how to handle this.

Please help.
TiA!
Mauro

bwoodsend

unread,
May 8, 2023, 3:57:24 AM5/8/23
to PyInstaller

The javascript stuff in pyqtlet2 itself is easy enough. The command line option --collect-data=pyqtlet2 to PyInstaller is enough which corresponds to a hook which looks like:

# hook-pyqtlet2.py from PyInstaller.utils.hooks import collect_data_files datas = collect_data_files("pyqtlet2")

If you wanted to make this available to everyone, you could upload it to the hooks repo or you can store it in pyqtlet2.

What’s rather more fiddly is the dependency on qtpy. Because qtpy is an abstraction layer across the Qt variants, it contains conditional imports which PyInstaller’s dependency scanner has no idea how to handle. I don’t think there’s any way of making that issue invisible. If you put in explicit imports to a specific Qt variant before any qtpy or pyqtlet2 imports, it behaves itself. i.e. The hello world pyqtlet2 example becomes:

import sys import PyQt6.QtWebEngineWidgets # <--- This line is different from qtpy.QtWidgets import QApplication, QVBoxLayout, QWidget from pyqtlet2 import L, MapWidget class MapWindow(QWidget): def __init__(self): # Setting up the widgets and layout super().__init__() self.mapWidget = MapWidget() self.layout = QVBoxLayout() self.layout.addWidget(self.mapWidget) self.setLayout(self.layout) # Working with the maps with pyqtlet self.map = L.map(self.mapWidget) self.map.setView([12.97, 77.59], 10) L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(self.map) self.marker = L.marker([12.934056, 77.610029]) self.marker.bindPopup('Maps are a treasure.') self.map.addLayer(self.marker) self.show() if __name__ == '__main__': app = QApplication(sys.argv) widget = MapWindow() sys.exit(app.exec_())
Reply all
Reply to author
Forward
0 new messages