网站搜索

将 PyGObject 应用程序和程序打包为 Linux 桌面的“.deb”包 – 第 4 部分


我们继续在 Linux 桌面上与您一起进行 PyGObject 编程系列,在该系列的第 4 部分中,我们将解释如何打包我们为Linux 桌面使用 PyGObject 作为 Debian 软件包。

Debian 软件包 (.deb) 是 Linux 下最常用的安装程序格式,处理 .deb 软件包的“dpkg”系统是所有基于 Debian 的 Linux 发行版(如 Ubuntu 和 Linux Mint)的默认设置。这就是为什么我们只解释如何为 Debian 打包我们的程序。

从 PyGObject 应用程序创建 Debian 软件包

首先,您应该具备一些有关创建 Debian 软件包的基本知识,以下指南将对您有很大帮助。

  1. Debian 打包简介

简而言之,如果您有名为“myprogram”的项目,它必须包含以下文件和文件夹,以便您可以打包它。

  1. debian(文件夹):此文件夹包含有关 Debian 软件包的所有信息,分为许多子文件。
  2. po(文件夹):po 文件夹包含程序的翻译文件(我们将在第 5 部分中解释)。
  3. myprogram(文件):这是我们使用 PyGObject 创建的 Python 文件,它是项目的主文件。
  4. ui.glade(文件):图形用户界面文件。如果您使用 Glade 创建应用程序的界面,则必须包含此文件
    你的项目。
  5. bMyprogram.desktop(文件):这是负责在应用程序菜单中显示应用程序的文件。
  6. setup.py(文件):该文件负责将任何Python程序安装到本地系统中,它在任何Python程序中都非常重要,它还有很多其他使用方式。

当然..您可以在项目中包含许多其他文件和文件夹(实际上您可以包含任何您想要的内容),但这些是基本的。

现在,让我们开始打包一个项目。创建一个名为“myprogram”的新文件夹,创建一个名为“myprogram”的文件,并向其中添加以下代码。

#!/usr/bin/python 
-*- coding: utf-8 -*- 

## Replace your name and email. 
My Name <[email > 

## Here you must add the license of the file, replace "MyProgram" with your program name. 
License: 
   MyProgram is free software: you can redistribute it and/or modify 
   it under the terms of the GNU General Public License as published by 
   the Free Software Foundation, either version 3 of the License, or 
   (at your option) any later version. 

   MyProgram is distributed in the hope that it will be useful, 
   but WITHOUT ANY WARRANTY; without even the implied warranty of 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
   GNU General Public License for more details. 

   You should have received a copy of the GNU General Public License 
   along with MyProgram.  If not, see <http://www.gnu.org/licenses/>. 

from gi.repository import Gtk 
import os 

class Handler: 
  
  def openterminal(self, button): 
    ## When the user clicks on the first button, the terminal will be opened. 
    os.system("x-terminal-emulator ") 
  
  def closeprogram(self, button): 
    Gtk.main_quit() 
    
Nothing new here.. We just imported the 'ui.glade' file. 
builder = Gtk.Builder() 
builder.add_from_file("/usr/lib/myprogram/ui.glade") 
builder.connect_signals(Handler()) 
window = builder.get_object("window1") 
window.connect("delete-event", Gtk.main_quit) 
window.show_all() 
Gtk.main()

创建一个 ui.glade 文件并用此代码填充它。

<?xml version="1.0" encoding="UTF-8"?> 
<!-- Generated with glade 3.16.1 --> 
<interface> 
  <requires lib="gtk+" version="3.10"/> 
  <object class="GtkWindow" id="window1"> 
    <property name="can_focus">False</property> 
    <property name="title" translatable="yes">My Program</property> 
    <property name="window_position">center</property> 
    <property name="icon_name">applications-utilities</property> 
    <property name="gravity">center</property> 
    <child> 
      <object class="GtkBox" id="box1"> 
        <property name="visible">True</property> 
        <property name="can_focus">False</property> 
        <property name="margin_left">5</property> 
        <property name="margin_right">5</property> 
        <property name="margin_top">5</property> 
        <property name="margin_bottom">5</property> 
        <property name="orientation">vertical</property> 
        <property name="homogeneous">True</property> 
        <child> 
          <object class="GtkLabel" id="label1"> 
            <property name="visible">True</property> 
            <property name="can_focus">False</property> 
            <property name="label" translatable="yes">Welcome to this Test Program !</property> 
          </object> 
          <packing> 
            <property name="expand">False</property> 
            <property name="fill">True</property> 
            <property name="position">0</property> 
          </packing> 
        </child> 
        <child> 
          <object class="GtkButton" id="button2"> 
            <property name="label" translatable="yes">Click on me to open the Terminal</property> 
            <property name="visible">True</property> 
            <property name="can_focus">True</property> 
            <property name="receives_default">True</property> 
            <signal name="clicked" handler="openterminal" swapped="no"/> 
          </object> 
          <packing> 
            <property name="expand">False</property> 
            <property name="fill">True</property> 
            <property name="position">1</property> 
          </packing> 
        </child> 
        <child> 
          <object class="GtkButton" id="button3"> 
            <property name="label">gtk-preferences</property> 
            <property name="visible">True</property> 
            <property name="can_focus">True</property> 
            <property name="receives_default">True</property> 
            <property name="use_stock">True</property> 
          </object> 
          <packing> 
            <property name="expand">False</property> 
            <property name="fill">True</property> 
            <property name="position">2</property> 
          </packing> 
        </child> 
        <child> 
          <object class="GtkButton" id="button4"> 
            <property name="label">gtk-about</property> 
            <property name="visible">True</property> 
            <property name="can_focus">True</property> 
            <property name="receives_default">True</property> 
            <property name="use_stock">True</property> 
          </object> 
          <packing> 
            <property name="expand">False</property> 
            <property name="fill">True</property> 
            <property name="position">3</property> 
          </packing> 
        </child> 
        <child> 
          <object class="GtkButton" id="button1"> 
            <property name="label">gtk-close</property> 
            <property name="visible">True</property> 
            <property name="can_focus">True</property> 
            <property name="receives_default">True</property> 
            <property name="use_stock">True</property> 
            <signal name="clicked" handler="closeprogram" swapped="no"/> 
          </object> 
          <packing> 
            <property name="expand">False</property> 
            <property name="fill">True</property> 
            <property name="position">4</property> 
          </packing> 
        </child> 
      </object> 
    </child> 
  </object> 
</interface>

到目前为止还没有什么新的东西。我们刚刚创建了一个 Python 文件及其接口文件。现在在同一文件夹中创建一个“setup.py”文件,并向其中添加以下代码,每一行都在注释中进行了解释。

Here we imported the 'setup' module which allows us to install Python scripts to the local system beside performing some other tasks, you can find the documentation here: https://docs.python.org/2/distutils/apiref.html 
from distutils.core import setup 

setup(name = "myprogram", # Name of the program. 
      version = "1.0", # Version of the program. 
      description = "An easy-to-use web interface to create & share pastes easily", # You don't need any help here. 
      author = "TecMint", # Nor here. 
      author_email = "[email ",# Nor here :D 
      url = "http://example.com", # If you have a website for you program.. put it here. 
      license='GPLv3', # The license of the program. 
      scripts=['myprogram'], # This is the name of the main Python script file, in our case it's "myprogram", it's the file that we added under the "myprogram" folder. 

Here you can choose where do you want to install your files on the local system, the "myprogram" file will be automatically installed in its correct place later, so you have only to choose where do you want to install the optional files that you shape with the Python script 
      data_files = [ ("lib/myprogram", ["ui.glade"]), # This is going to install the "ui.glade" file under the /usr/lib/myprogram path. 
                     ("share/applications", ["myprogram.desktop"]) ] ) # And this is going to install the .desktop file under the /usr/share/applications folder, all the folder are automatically installed under the /usr folder in your root partition, you don't need to add "/usr/ to the path. 

现在在同一文件夹中创建一个“myprogram.desktop”文件,并添加以下代码,注释中也有解释。

This is the .desktop file, this file is the responsible file about showing your application in the applications menu in any desktop interface, it's important to add this file to your project, you can view more details about this file from here: https://developer.gnome.org/integration-guide/stable/desktop-files.html.en 
[Desktop Entry] 
The default name of the program. 
Name=My Program 
The name of the program in the Arabic language, this name will be used to display the application under the applications menu when the default language of the system is Arabic, use the languages codes to change the name for each language. 
Name[ar]=برنامجي 
Description of the file. 
Comment=A simple test program developed by me. 
Description of the file in Arabic. 
Comment[ar]=برنامج تجريبي بسيط تم تطويره بواسطتي. 
The command that's going to be executed when the application is launched from the applications menu, you can enter the name of the Python script or the full path if you want like /usr/bin/myprogram 
Exec=myprogram 
Do you want to run your program from the terminal? 
Terminal=false 
Leave this like that. 
Type=Application 
Enter the name of the icon you want to use for the application, you can enter a path for the icon as well like /usr/share/pixmaps/icon.png but make sure to include the icon.png file in your project folder first and in the setup.py file as well. Here we'll use the "system" icon for now. 
Icon=system 
The category of the file, you can view the available categories from the freedesktop website.
Categories=GNOME;GTK;Utility; 
StartupNotify=false 

现在我们已经差不多完成了。我们只需在“debian”文件夹下创建一些小文件,以便提供有关“dpkg”包的信息系统。

打开“debian”文件夹,并创建以下文件。

control
compat
changelog
rules

control:该文件提供了 Debian 软件包的基本信息,有关更多详细信息,请访问 Debian 软件包控制字段。

Source: myprogram
Maintainer: My Name <[email > 
Section: utils 
Priority: optional 
Standards-Version: 3.9.2 
Build-Depends: debhelper (>= 9), python2.7 

Package: myprogram 
Architecture: all 
Depends: python-gi 
Description: My Program 
Here you can add a short description about your program.

compat:这只是dpkg系统的一个重要文件,它只包含神奇的9数字,就这样吧。

9

变更日志:您可以在此处添加对程序所做的更改,有关更多信息,请访问 Debian 软件包变更日志源。

myprogram (1.0) trusty; urgency=medium 

  * Add the new features here. 
  * Continue adding new changes here. 
  * And here. 

 -- My Name Here <[email >  Sat, 27 Dec 2014 21:36:33 +0200

rules:该文件负责在本地机器上运行安装过程来安装软件包,您可以查看更多信息
有关此文件的信息,请参见此处:Debian 软件包默认规则。

尽管您的 Python 程序不再需要任何东西。

#!/usr/bin/make -f 
This file is responsible about running the installation process on the local machine to install the package, you can view more information about this file from here: https://www.debian.org/doc/manuals/maint-guide/dreq.en.html#defaultrules Though you won't need anything more for your Python program. 
%: 
    dh $@ 
override_dh_auto_install: 
    python setup.py install --root=debian/myprogram --install-layout=deb --install-scripts=/usr/bin/ # This is going to run the setup.py file to install the program as a Python script on the system, it's also going to install the "myprogram" script under /usr/bin/ using the --install-scripts option, DON'T FORGET TO REPLACE "myprogram" WITH YOUR PROGRAM NAME. 
override_dh_auto_build:

现在我们成功地为我们的程序创建了所有必需的文件,现在让我们开始打包它。首先,确保在开始之前已经安装了构建过程的一些依赖项。

sudo apt-get update
sudo apt-get install devscripts

现在假设“myprogram”文件夹位于您的主文件夹 (/home/user/myprogram) 中,为了将其打包为 Debian 软件包,请运行以下命令。

cd /home/user/myprogram
debuild -us -uc
样本输出
hanny@hanny-HP-Pavilion-15-Notebook-PC:~/Projects/myprogram$
debuild -us -uc dpkg-buildpackage -rfakeroot -D -us -uc
dpkg-buildpackage: source package myprogram
dpkg-buildpackage: source version 1.0
dpkg-buildpackage: source distribution trusty
dpkg-buildpackage: source changed by My Name Here
<[email >
dpkg-source --before-build myprogram
dpkg-buildpackage: host architecture i386
fakeroot debian/rules clean
dh clean
dh_testdir
dh_auto_clean
....
.....
Finished running lintian.

就是这样!您的 Debian 软件包已成功创建:

为了将其安装在任何基于 Debian 的发行版上,请运行。

sudo dpkg -i myprogram_1.0_all.deb

不要忘记将上面的文件替换为包的名称。现在,安装包后,您可以从应用程序菜单运行该程序。

它会起作用..

关于 PyGObject 的系列的第四部分到此结束。在下一课中,我们将解释如何轻松本地化 PyGObject 应用程序,在此之前请继续关注......