Az alkalmazás csomagolása és terjesztése elvileg egyszerűen hangzik. Ez csak szoftver. De a gyakorlatban ez elég nagy kihívást jelent.
A Sofi nevű Python modulon dolgoztam, amely felhasználói felületeket generál. Asztali hangulatot keltheti a szabványos egyoldalas webes technológiák használata közben. A rugalmasság érdekében úgy terveztem, hogy két terjesztési módszeren keresztül működjön: böngészőben és futtatható módon.
A böngészőben futva ugyanúgy működik, mint egy normál weboldal. Betöltheti egy fájl megnyitásával, vagy elindíthatja a shell-jéből. Építettem egy futtatható fájlt is, amely csomagolt alkalmazásként fut, független és külső követelmények nélkül.
Idővel, amikor feltörtem az Atom kódját - manapság a szerkesztőm volt -, eszembe jutott, hogy az Atom valójában egy böngésző. Háttérként a Node.js-t, felhasználói felületéhez pedig az Electron keretrendszert használja. Ez arra ösztönzött, hogy elkezdtem piszkálni az Electron belső terét, remélve, hogy találok példákat és legjobb gyakorlatokat az asztali csomagolások megoldására.
Nem kellett sokáig felfedeznem, hogy mindez ingyenes és nyílt forráskódú technológiákra épül: a Chromium böngészőre és a Chromium Embedded Framework-re. Ez olyan könnyen integrálható példa testreszabásokat tartalmazott, amelyek képesek voltak megfelelni a követelményeimnek.
Mindezzel a kezemben dolgozni kezdtem.
A Chromium Embedded Framework
A Chromium az az alapkód, amely a Google Chrome böngészőjét táplálja. Összegyűjti az összes olyan elemet, amely egy felületet megjelenít, feldolgozza a felhasználói adatbevitelt és parancsfájljait.
A Chromium Embedded Framework (CEF) a C funkciók csoportja, amelyek vezérelhetik az adott böngészőt. Szkripteket is kínál, amelyek egyszerűsítik az összeállítás és az összeállítás folyamatát.
A Visual Studio Code, a Slack, a Mattermost, az Curse, a Postman és a Kitematic mind az Electronot használó asztali alkalmazások példái. Ezek a rendszerek mind olyan webhelyeknek minősülnek, amelyek kihasználják az alatta található böngészőt a CEF segítségével.
Ha arra gondolsz, hogy a Python képes kötődni a C-hez és kihasználni ezeket a funkciókat is, akkor igazad van. Ne keresse tovább a pycef projektet, hogy közvetlenül meghívja a CEF burkoló funkcióit. Ugyanakkor jár hozzá a Chromium bináris, mint hozzáadott függőség. Tehát, ha aggódik a bonyolult támogatási nyilatkozatok kezelése miatt, gondold át, mielőtt ugranál.
Sajátos helyzetemben a Sofi projekt minden interakciót webaljzaton keresztül kezel, következetes felületet biztosítva a különböző típusú platformokon (web, asztali, mobil stb.). Ez azt jelenti, hogy nem kell manuálisan parancsolgatnom vagy meghajtanom a böngészőt. Csak a DOM-mal szeretnék kölcsönhatásba lépni, amelyet a böngésző a szokásos webes technológiákon keresztül jelenít meg.
Célom az UI-elemek testreszabása, amelyek a böngészőt böngészőszerűvé teszik. El kell távolítanom a menüket, az eszköztárakat és az állapotsorokat. Ennek során azt fogom megmutatni, hogy teljes képernyős módban vagyunk - de egy alkalmazásablakon belül.
Egyszerű követelményeimre való tekintettel úgy éreztem, hogy a pycef - vagy bármilyen más alacsonyabb szintű kötés - túl sok. Ehelyett egy előre elkészített mintát használtam a CEF projektből: cefsimple . Ez a böngésző elrejti az összes kívánt vizuális elemet, így ha a CLI-t használom egy weboldal megnyitására, a felhasználónak fogalma sincs arról, hogy valójában egy böngészőben vannak. Úgy néz ki, mint egy szokásos ablak bármely alkalmazásból.
A cefsimple építése nem volt túl bonyolult, miután átnéztem a dokumentációt. De óriási időbe telik, ha a Chromiumot is felépíti vele együtt. Ennek elkerülése érdekében a projekt maga tartalmaz előre elkészített bináris fájlokat, amelyeket testreszabhat és cefsimple-be fordíthat. Azt találtam a legjobbnak, hogy ezeket kihasználom.
A lépések a következők:
- Nézze át gyorsan, hogyan lehet bináris fájlokból építkezni a CEF-fel.
- Fogja meg a repo egyik bináris eloszlását. Mielőtt kiválasztaná, feltétlenül olvassa el az eszköztippeket, mivel nem minden csomag tartalmazza ugyanazt a fájlt. Kifejezetten kerestem egyet
cefsimple
. - Nézze át a
CMakeLists.txt
fájlt, és győződjön meg arról, hogy telepítette a szükséges buildeszközöket. Ez platformspecifikus. - Végezze el a felépítést. Ezt ugyanabban a fájlban magyarázzák, mint az előző lépést, és szintén platformspecifikus, de hajlamos követni a következő folyamatokat: make és cd a build könyvtárba, a cmake futtatása a fordítóeszközökhöz és az építészethez, miközben a szülő könyvtárra mutat. Mivel az OSX Ninja eszközöket 64 bites platformon használtam, a parancs úgy nézett ki
cmake -G "Ninja" -DPROJECT_ARCH="x86_64" ..
- A build könyvtár tartalmazza majd a kimeneti fájlokat. A szerkezet kissé zavaró lehet, de a fő részben le van írva
README
. Hivatkozásként az előző lépés egy alkalmazáscsomagot eredményezettbuild/tests/cefsimple/Release/cefsimple.app
. - Ne felejtse el, hogy ezt meg kell tennie, hogy létrehozza a szükséges bináris fájlokat minden támogatott platformhoz és operációs rendszer architektúrához.
Most, hogy van egy futtatható fájlja, futtassa azt a parancssorból a --url
set beállítással a megnyitni kívánt weboldalra. Ez azt jelenti, hogy a Python szkriptbe történő beépítése egyszerűen elvégezhető a subprocess
modulon keresztül .
Bár nem kötelező, ha érdekli maga a Chromium fordítása, nézze meg a CEF dokumentációját. Ez jó irányba mutat. Figyelem: a letöltés, összeállítás és összeállítás sok időt vesz igénybe. A régimódi feldolgozó lóerő mindenképpen segít a gyorsabb eredmények elérésében.
Csomagolás
Most, hogy asztali élményt tudunk nyújtani, meg kell fontolnunk, hogyan terjesszük ezt a felhasználóknak. A hagyományos Python csomagterjesztés a Python Package Index (PyPI) segítségével valósul meg. Mindazonáltal megköveteli a felhasználóinktól, hogy telepítsék a Python tolmácsot és valamilyen csomagolóeszközt, például a easy_install
vagy -t pip
.
Bár ez nem különösebben nehéz, érdemes figyelembe venni a felhasználók szélesebb körét. A telepítési folyamat kezelése külön kézi lépésekkel meglehetősen bonyolulttá válik. Különösen nem technikai közönségnél - akik közül néhányan nem tudják, hogy a Python nem más, mint egy nagy kígyó. Míg mások legalább ismerhetik az európai teher nélküli fecske sebességét.
Ha tudják a nyelvet, a legtöbbnek már van saját verziója. Itt játsszák a csomagfüggőségeket, a különböző operációs rendszereket, olyan böngészőket, amelyekről még soha nem hallottak (vagy amiről azt hitték, hogy már elhunytak), valamint a felhasználók virtuális környezetek felállításával kapcsolatos eltérő képességeivel. Ez általában sok időt fordít az egymással nem illő szoftverek támogatására.
Az ilyen nagy rendetlenség elkerülése érdekében vannak olyan eszközök, amelyek az összes függőséget beágyazhatják az operációs rendszer-specifikus futtatható fájlokba. Alapos megfontolás után a PyInstaller az, akit törekvéseimhez választottam. Úgy tűnik, hogy ez biztosítja a legtöbb rugalmasságot a támogatott platformokon és formátumokban.
A GitHub-tárház rövid kivonata szépen összefoglalja a dolgokat:
A PyInstaller elolvassa az Ön által írt Python szkriptet. Elemzi a kódot, hogy felfedezzen minden más modult és könyvtárat, amelyre a szkriptnek szüksége van a végrehajtáshoz. Ezután összegyűjti az összes fájl másolatát - beleértve az aktív Python tolmácsot is! - és a szkripteddel egyetlen mappába, vagy opcionálisan egyetlen futtatható fájlba helyezi őket.Az eszköz teljesítette ígéretét. Rámutattam, hogy a Python fájl mintám kérelmet, és azt kötegek ez egy könyvtárban könnyen elég: pyinstaller sample.py
. Amikor futtatható fájlt akarok, csak adja hozzá a --onefile
paramétert.
Kicsit bonyolultabb lesz, ha nem Python-adatokat kell hozzáadnia a csomaghoz. Ez a helyzet a Sofi alapját képező html és js fájlokkal, valamint a cefsimple böngészővel, amely az alkalmazás felületét mutatja be korábban. A PyInstaller segédprogram --add-data
éppen ezt biztosítja, lehetővé téve a köteg azon útvonalának leképezését, ahol az adatfájl (vagy könyvtár) található. Azonban eltartott egy ideig, mire rájöttem, hogyan lehet megfelelő módon elérni ezeket a könyvtárakat a kódomon belül. Szerencsére a dokumentáció a helyes irányba mutatott.
Mint kiderült, egy PyInstaller csomagban futó alkalmazás futtatásakor nem támaszkodhat __file__
és hasonló mechanizmusokra az útvonalak meghatározásához. Ehelyett a PyInstaller rendszerbetöltő tárolja a csomag abszolút elérési útját, sys._MEIPASS
és hozzáad egy frozen
attribútumot, hogy tudassa veled, hogy egy csomagban futsz. Ha sys.frozen
az, True
akkor töltse be a fájlokat az alapján sys._MEIPASS
, különben használja a normál elérési út funkciókat annak meghatározásához, hogy hol vannak a dolgok.
Sikeresen létrehozhattam egy OSX csomagba rendezett alkalmazást és egy futtatható Linux bináris verziót ugyanabból a Python szkriptből. Ellenőriztem, hogy ugyanezt meg tudom-e csinálni egy Windows futtatható programmal is, de még nem volt időm összeállítani a cefsimple böngésző Windows verzióját a csomag elérési útjának tesztelésére.
A végtermék
Az itt leírt rendszerhez csomagolt böngésző-alapú felhasználói felület példájához tekintse meg a PyCaribbean 2017 előadásomat.
A CEF és a csomagolás szempontjából releváns bemutató képgaléria, és 18:15 körül jelenik meg.
További információt arról, hogyan készítettem Sofit, tekintse meg az A Python Ate My GUI sorozatot.
Ha tetszett a cikk, és többet szeretne megtudni a Pythonról és a szoftveres gyakorlatokról, látogasson el a tryexceptpass.org oldalra. A levelezőlistára való feliratkozással folyamatosan értesülhet legújabb tartalmaikról.