chromium 桌面
Packaging and distributing your app sounds simple in principle. It’s just software. But in practice, it’s quite challenging.
打包和分發應用程序在原理上聽起來很簡單。 這只是軟件。 但是在實踐中,這非常具有挑戰性。
I’ve been working on a Python module called Sofi that generates user interfaces. It can deliver a desktop feel while using standard single-page web technologies. For flexibility, I designed it to work through two methods of distribution: in-browser and executable.
我一直在研究一個名為Sofi的Python模塊,該模塊可生成用戶界面。 使用標準單頁Web技術時,它可以提供桌面感覺。 為了提高靈活性,我將其設計為通過兩種分發方法進行工作:瀏覽器內和可執行文件。
Running in the browser, it functions much like a normal webpage. You can load it by opening a file, or launch it from your shell. I also built an executable that runs as a packaged app, independent and without external requirements.
它運行在瀏覽器中,功能類似于普通網頁。 您可以通過打開文件來加載它,或者從您的Shell中啟動它。 我還構建了一個可執行文件,該可執行文件作為打包的應用程序運行,獨立且沒有外部需求。
Over time, as I hacked at code in Atom — my editor of choice these days — I remembered that Atom is actually a browser. It uses Node.js as a back end, and the Electron framework for its user interface. This inspired me to start poking at Electron’s internals, hoping to find examples and best practices on how they solved desktop packaging.
隨著時間的流逝,當我黑客攻擊Atom(這是我如今的首選編輯器)中的代碼時,我記得Atom實際上是一個瀏覽器。 它使用Node.js作為后端,并使用Electron框架作為其用戶界面。 這啟發了我開始研究Electron的內部結構,希望找到有關如何解決臺式機包裝的示例和最佳實踐。
It didn’t take long for me to discover that it’s all built on top of free and open sourced technologies: the Chromium browser and the Chromium Embedded Framework. This featured easy-to-integrate example customizations that were capable of fulfilling my requirements.
我花了很長時間才發現它們全部建立在免費和開源技術之上:Chromium瀏覽器和Chromium嵌入式框架 。 這個功能具有易于集成的示例定制功能,可以滿足我的要求。
With all this in hand, I got to work.
有了這些,我就可以工作了。
Chromium嵌入式框架 (The Chromium Embedded Framework)
Chromium is the base code that feeds Google’s Chrome browser. It brings together all the elements that render an interface, process user input, and script its functions.
Chromium是Google Chrome瀏覽器的基本代碼。 它匯集了呈現界面,處理用戶輸入并編寫其功能腳本的所有元素。
The Chromium Embedded Framework (CEF) is a group of C functions that that can control that browser. It also provides scripts that help simplify the process of building and compiling it.
Chromium嵌入式框架(CEF)是一組C函數,可以控制該瀏覽器。 它還提供了有助于簡化構建和編譯過程的腳本。
Visual Studio Code, Slack, Mattermost, Curse, Postman, and Kitematic are all examples of desktop apps that use Electron. These systems all qualify as websites that exploit the browser underneath with CEF.
Visual Studio Code,Slack,Mattermost,Curse,Postman和Kitematic都是使用Electron的桌面應用程序的示例。 這些系統都可以作為利用CEF開發其瀏覽器的網站。
If you’re thinking that Python can bind with C and take advantage of these features as well, then you’re right. Look no further than the pycef project to call the CEF wrapper functions directly. However, it does come with the Chromium binary as an added dependency. So if you’re worried about managing complicated support statements, think before you jump.
如果您認為Python可以與C綁定并且也可以利用這些功能,那么您是對的。 可以直接使用pycef項目直接調用CEF包裝函數。 但是,它確實附帶了Chromium二進制文件作為附加的依賴項。 因此,如果您擔心管理復雜的支持聲明,請在跳樓之前考慮一下。
In my particular situation, the Sofi project manages all interactions through a websocket, providing a consistent interface across different types of platforms (web, desktop, mobile, etc.). This means I don’t need to manually commanding or drive the browser. I only wish to interact with the DOM that the browser displays through standard web technologies.
在我的特定情況下,Sofi項目通過Websocket管理所有交互,從而在不同類型的平臺(Web,桌面,移動等)之間提供一致的界面。 這意味著我不需要手動命令或驅動瀏覽器。 我只希望與瀏覽器通過標準Web技術顯示的DOM進行交互。
My goal is to customize the UI elements that make a browser look like a browser. I need to remove the menus, toolbars, and status bars. In doing so, I’ll make it appear that we’re in fullscreen mode — but inside an application window.
我的目標是定制使瀏覽器看起來像瀏覽器的UI元素。 我需要刪除菜單,工具欄和狀態欄。 這樣做時,我看起來似乎處于全屏模式下-但在應用程序窗口內。
Given my simple requirements, I felt that pycef — or any other lower-level bindings — was too much. Instead I took advantage of a pre-built sample from the CEF project: cefsimple. This browser hides all the visual elements I want, so if I use its CLI to open a webpage, the user has no idea that they’re actually inside a browser. It looks like a regular window from any application.
鑒于我的簡單要求,我覺得pycef或其他任何較低級別的綁定都太多了。 相反,我利用了CEF項目中的預構建示例: cefsimple 。 該瀏覽器隱藏了我想要的所有可視元素,因此,如果我使用其CLI來打開網頁,則用戶不知道它們實際上在瀏覽器中。 它看起來像來自任何應用程序的常規窗口。
Building cefsimple wasn’t too complicated once I went through the documentation. But it takes an enormous amount of time if you also build Chromium along with it. To avoid this, the project itself provides pre-built binaries that you can customize and compile into cefsimple. I found it best to take advantage of these.
閱讀文檔后,構建cefsimple并不太復雜。 但是,如果您還同時構建Chromium,則會花費大量時間。 為避免這種情況,項目本身提供了預構建的二進制文件,您可以對其進行自定義并將其編譯為cefsimple。 我發現最好利用這些。
The steps are as follows:
步驟如下:
Have a quick look through how to build with CEF from binaries.
快速瀏覽一下如何使用二進制文件中的CEF 進行構建 。
Grab one of the binary distributions from the repo. Be sure to read the tooltips before selecting one, since not all packages contain the same files. I was specifically looking for one with
cefsimple
.從倉庫中獲取二進制分布之一。 選擇一項之前,請務必先閱讀工具提示,因為并非所有軟件包都包含相同的文件。 我專門在找
cefsimple
。Look through the
CMakeLists.txt
file and make sure you install the necessary build tools. This is platform specific.瀏覽
CMakeLists.txt
文件,并確保安裝了必要的構建工具。 這是特定于平臺的。Perform the build. This is explained in the same file as the previous step and is also platform specific, but it tends to follow the process of: make and cd into build directory, run cmake for your compilation tools and architecture while pointing at the parent directory. Since I used the OSX Ninja tools on a 64-bit platform, the command looked like
cmake -G "Ninja" -DPROJECT_ARCH="x86_64" ..
執行構建。 這在與上一步相同的文件中進行了說明,并且也是特定于平臺的,但是它傾向于遵循以下過程:make和cd進入build目錄,在指向父目錄的同時為您的編譯工具和體系結構運行cmake。 由于我在64位平臺上使用OSX Ninja工具,因此該命令看起來像
cmake -G "Ninja" -DPROJECT_ARCH="x86_64" ..
The build directory will now contain the output files. The structure can be a little confusing, but it’s described in the main
README
. As a reference, the previous step resulted in an app bundle underbuild/tests/cefsimple/Release/cefsimple.app
.現在,構建目錄將包含輸出文件。 該結構可能會有些混亂,但主要
README
對此進行了描述。 作為參考,上一步產生了build/tests/cefsimple/Release/cefsimple.app
下的應用程序捆綁包。- Don’t forget you’ll have to do this to create the binaries you need for every platform and OS architecture that your supporting. 別忘了,您將必須執行此操作來創建支持的每個平臺和OS體系結構所需的二進制文件。
Now that you have an executable, run it from command line with --url
set to the webpage you want to open. This means that incorporating it into a Python script is easily done through the subprocess
module.
既然您已經有了可執行文件,請從命令行運行它,并將--url
設置為要打開的網頁。 這意味著可以通過subprocess
模塊輕松地將其合并到Python腳本中。
While not required, if you’re interested in compiling Chromium itself, have a look at the CEF documentation. It will point you in the right direction. But be warned, it takes a lot of time to download, build and compile. Good old fashioned processing horsepower will definitely help get faster results.
盡管不是必需的,但是如果您有興趣編譯Chromium本身,請查看CEF文檔。 它將為您指明正確的方向。 但請注意,下載,構建和編譯需要大量時間。 好的老式處理能力肯定會幫助您更快地獲得結果。
打包 (Packaging)
Now that we can deliver a desktop experience, we have to consider how to distribute that to our users. Traditional Python package distribution is accomplished through the Python Package Index (PyPI). However, it requires our users to install the Python interpreter and some form of packaging tool like easy_install
or pip
.
現在我們可以提供桌面體驗,我們必須考慮如何將其分發給我們的用戶。 傳統的Python軟件包分發是通過Python軟件包索引(PyPI)完成的。 但是,它要求我們的用戶安裝Python解釋器和某種形式的打包工具,例如easy_install
或pip
。
While this isn’t particularly hard, you should consider the wider range of users. Managing an install process with separate manual steps gets fairly complicated. Especially with non-technical audiences — some of whom don’t know that Python is anything other than a large snake. While others may at least know the air speed velocity of a European unladen swallow.
盡管這并不是特別困難,但您應該考慮更多的用戶。 使用單獨的手動步驟來管理安裝過程變得相當復雜。 尤其是對于非技術人員來說-有些人不知道Python只是一條大蛇。 而其他人可能至少知道歐洲空載燕子的風速。
If they do know the language, most already have their own version installed. This is where package dependencies, different operating systems, browsers you’ve never heard of (or thought were dead by now) come into play, along with users’ varying skills in setting up virtual environments. This tends to translate into a large amount of time spent supporting mismatched software.
如果他們知道該語言,則大多數人已經安裝了自己的版本。 這是軟件包依賴性,不同的操作系統,您從未聽說過(或現在認為已經死掉)的瀏覽器以及用戶設置虛擬環境的各種技能的地方。 這往往會轉化為花費大量時間來支持不匹配的軟件。
To avoid such a large mess, there are tools that can embed all your dependencies into OS-specific executable files. After careful consideration, the one I chose for my endeavors is PyInstaller. It seems to provide the most flexibility in supported platforms and formats.
為避免造成如此大的混亂,有些工具可以將所有依賴項嵌入到特定于OS的可執行文件中。 經過仔細考慮,我選擇的一個是PyInstaller 。 它似乎在受支持的平臺和格式中提供了最大的靈活性。
A brief excerpt from their GitHub repository sums things up nicely:
他們的GitHub存儲庫的簡短摘錄很好地總結了這些內容:
PyInstaller reads a Python script written by you. It analyzes your code to discover every other module and library your script needs in order to execute. Then it collects copies of all those files — including the active Python interpreter! — and puts them with your script in a single folder, or optionally in a single executable file.
PyInstaller讀取您編寫的Python腳本。 它分析您的代碼以發現腳本執行所需的所有其他模塊和庫。 然后,它將收集所有這些文件的副本-包括活動的Python解釋器! —并將它們與腳本一起放在單個文件夾中,或者可選地在單個可執行文件中。
The tool delivered on its promise. I pointed it to the Python file for my sample application and it bundles it in a directory easily enough with: pyinstaller sample.py
. When I want an executable instead, just add the --onefile
parameter.
該工具兌現了承諾。 我將其指向示例應用程序的Python文件,并使用pyinstaller sample.py
輕松將其捆綁在一個目錄中。 當我需要可執行文件時,只需添加--onefile
參數。
It gets a bit trickier when you need to add non-Python data to your bundle. This is the case with the html and js files that form the basis of Sofi, and the cefsimple browser that presents the application interface from earlier. The PyInstaller utility provides --add-data
to do just that, allowing a mapping to the path within your bundle where the data file (or directory) will reside. However, it took me a while to figure out how to properly access those directories from within my code. Luckily the documentation pointed me in the right direction.
當您需要將非Python數據添加到包中時,它會變得有些棘手。 構成Sofi的html和js文件就是這種情況,而cefsimple瀏覽器則提供了較早版本的應用程序界面。 PyInstaller實用程序提供--add-data
來執行此操作,從而允許映射到包中數據文件(或目錄)將駐留的路徑。 但是,花了我一段時間才弄清楚如何從我的代碼中正確訪問那些目錄。 幸運的是,文檔為我指明了正確的方向。
As it turns out, when running a PyInstaller bundled application, you can’t rely on __file__
and similar mechanisms to determine paths. Instead, the PyInstaller bootloader stores the absolute path to the bundle in sys._MEIPASS
and adds a frozen
attribute to let you know that you’re running inside a bundle. If sys.frozen
is True
then load your files based on sys._MEIPASS
, otherwise use normal path functions to determine where things are.
事實證明,在運行PyInstaller捆綁的應用程序時,您不能依賴__file__
和類似的機制來確定路徑。 相反,PyInstaller引導加載程序將捆綁軟件的絕對路徑存儲在sys._MEIPASS
并添加一個frozen
屬性以讓您知道您正在捆綁軟件中運行。 如果sys.frozen
為True
則基于sys._MEIPASS
加載文件,否則使用常規路徑函數確定對象的位置。
I was able to successfully create both an OSX bundled app and an executable Linux binary of the same Python script. I verified I can do the same with a Windows executable, but haven’t had time to put together a Windows version of the cefsimple browser to test the bundle path yet.
我能夠成功創建OSX捆綁的應用程序和相同Python腳本的可執行Linux二進制文件。 我確認可以使用Windows可執行文件執行相同的操作,但是還沒有時間將Windows版本的cefsimple瀏覽器放在一起以測試捆綁包路徑。
最終產品 (The Final Product)
For an example of the browser-based user interface packaged with the system described here, have a look at my presentation at PyCaribbean 2017.
對于此處描述的系統打包的基于瀏覽器的用戶界面的示例,請查看我在PyCaribbean 2017上的演示。
The demo relevant to CEF and packaging is of an image gallery and it appears around 18:15.
與CEF和包裝相關的演示是一個圖片庫,它于18:15左右出現。
For additional reading on how I made Sofi, have a look at the A Python Ate My GUI series.
有關我如何制作Sofi的更多信息,請閱讀A Python Ate My GUI系列。
If you liked the article and want to read more about Python and software practices, please visit tryexceptpass.org. Stay informed with their latest content by subscribing to the mailing list.
如果您喜歡這篇文章,并想了解有關Python和軟件實踐的更多信息,請訪問tryexceptpass.org 。 訂閱郵件列表,隨時了解其最新內容。
翻譯自: https://www.freecodecamp.org/news/the-python-desktop-application-3a66b4a128d3/
chromium 桌面