{"id":12017,"date":"2019-03-21T03:06:52","date_gmt":"2019-03-21T03:06:52","guid":{"rendered":"http:\/\/www.appservgrid.com\/paw92\/?p=12017"},"modified":"2019-03-21T03:06:52","modified_gmt":"2019-03-21T03:06:52","slug":"how-to-create-gui-applications-under-linux-desktop-using-pygobject","status":"publish","type":"post","link":"https:\/\/www.appservgrid.com\/paw92\/index.php\/2019\/03\/21\/how-to-create-gui-applications-under-linux-desktop-using-pygobject\/","title":{"rendered":"How to Create GUI Applications Under Linux Desktop Using PyGObject"},"content":{"rendered":"<p>Creating applications on Linux can be done using different ways, but there are a limited ways of doing, so using the simplest and the most functional programming languages and libraries, that\u2019s why we\u2019re going to have a quick look about creating applications under the Linux desktop using the GTK+ library with Python programming language which is called \u201c<strong>PyGObject<\/strong>\u201d.<\/p>\n<p><strong>PyGObject<\/strong>\u00a0uses the GObject Introspection to create binding for programming languages like Python, PyGObject is the next generation from PyGTK, you can say that PyGObject = Python + GTK3.<\/p>\n<div id=\"attachment_9840\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Create-Applications-in-Linux-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-9840\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Create-Applications-in-Linux-1.png\" alt=\"Create GUI Applications in Linux \" width=\"600\" height=\"400\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create GUI Applications in Linux \u2013 Part 1<\/p>\n<\/div>\n<p>Today, we\u2019re going to start a series about creating GUI (Graphical User Interface) applications under the Linux desktop using GTK+ library and\u00a0<b>PyGobject<\/b>\u00a0language, the series will cover the following topics:<\/p>\n<div id=\"exam_announcement\"><b>Part 1<\/b>:\u00a0<b>How to Create GUI Applications Under Linux Desktop Using PyGObject<\/b><\/div>\n<div id=\"exam_announcement\"><b>Part 2<\/b>:\u00a0<a href=\"https:\/\/www.tecmint.com\/create-more-advance-gui-applications-in-linux\/\" target=\"_blank\" rel=\"noopener\">Creating More Advance PyGobject Applications on Linux<\/a><\/div>\n<div id=\"exam_announcement\"><b>Part 3<\/b>:\u00a0<a href=\"https:\/\/www.tecmint.com\/create-web-brower-and-recorder-using-pygobject\/\" target=\"_blank\" rel=\"noopener\">Create Your Own \u2018Web Browser\u2019 and \u2018Desktop Recorder\u2019 Applications Using PyGobject<\/a><\/div>\n<div id=\"exam_announcement\"><b>Part 4<\/b>:\u00a0<a href=\"https:\/\/www.tecmint.com\/package-pygobject-applications-as-deb-package\/\" target=\"_blank\" rel=\"noopener\">Packaging PyGobject Programs for the Linux Desktop<\/a><\/div>\n<div id=\"exam_announcement\"><b>Part 5<\/b>:\u00a0<a href=\"https:\/\/www.tecmint.com\/translate-pygobject-applications-into-different-languages-in-linux\/\" target=\"_blank\" rel=\"noopener\">Translating PyGobject Applications into Different Languages<\/a><\/div>\n<h5>About Python<\/h5>\n<p>First of all, you must have some basic knowledge in Python;\u00a0<b>Python<\/b>\u00a0is a very modern and easy to use programming language. It\u2019s one of the most famous programming languages in the world, using Python, you will be able to create many great applications &amp; tools. You may take some free courses like those at\u00a0<a href=\"https:\/\/www.codecademy.com\/en\/tracks\/python\" target=\"_blank\" rel=\"nofollow noopener\">codeacademy.com<\/a>\u00a0or you may read some books about Python at:<\/p>\n<p><b>GTK+<\/b>\u00a0is an open-source cross-platform toolkit to create graphical user interfaces for desktop applications, it was first started in 1998 as a GUI toolkit for the GIMP, later, it was used in many other applications and soon became one of the most famous libraries to create GUIs. GTK+ is released under the LGPL license.<\/p>\n<h3>Creating GUI Applications Under Linux<\/h3>\n<p>There are 2 ways for creating the applications using GTK+ &amp; Python:<\/p>\n<ol>\n<li>Writing the graphical interface using code only.<\/li>\n<li>Designing the graphical interface using the \u201c<b>Glade<\/b>\u201d program; which is RAD tool to design GTK+ interfaces easily, Glade generates the GUI as a XML file which can be used with any programming language to build the GUI, after exporting the GUI\u2019s XML file, we\u2019ll be able to link the XML file with our program to do the jobs we want.<\/li>\n<\/ol>\n<p>We\u2019ll explain both ways in short.<\/p>\n<h4>The Code-Only Way<\/h4>\n<p>Writing the GUI using code only can be little bit hard for noob programmer\u2019s and very time-wasting, but using it, we can create very functional GUIs for our programs, more than those we create using some tools like Glade.<\/p>\n<p>Let\u2019s take the following example.<\/p>\n<pre>#!\/usr\/bin\/python\r\n# -*- coding: utf-8 -*-\r\n\r\nfrom gi.repository import Gtk\r\n\r\nclass ourwindow(Gtk.Window):\r\n\r\n    def __init__(self):\r\n        Gtk.Window.__init__(self, title=\"My Hello World Program\")\r\n        Gtk.Window.set_default_size(self, 400,325)\r\n        Gtk.Window.set_position(self, Gtk.WindowPosition.CENTER)\r\n\r\n        button1 = Gtk.Button(\"Hello, World!\")\r\n        button1.connect(\"clicked\", self.whenbutton1_clicked)\r\n\r\n        self.add(button1)\r\n        \r\n    def whenbutton1_clicked(self, button):\r\n      print \"Hello, World!\"\r\n\r\nwindow = ourwindow()        \r\nwindow.connect(\"delete-event\", Gtk.main_quit)\r\nwindow.show_all()\r\nGtk.main()\r\n<\/pre>\n<p>Copy the above code, paste it in a \u201c<b>test.py<\/b>\u201d file and set 755 permission on the test.py file and run the file later using \u201c<b>.\/test.py<\/b>\u201d, that\u2019s what you will get.<\/p>\n<pre># nano test.py\r\n# chmod 755 test.py\r\n# .\/test.py\r\n<\/pre>\n<div id=\"attachment_9821\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Hello-World-Script.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-9821\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Hello-World-Script.png\" alt=\"Hello World Script\" width=\"474\" height=\"410\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Hello World Script<\/p>\n<\/div>\n<p>By clicking the button, you see the \u201c<b>Hello, World!<\/b>\u201d sentence printed out in the terminal:<\/p>\n<div id=\"attachment_9838\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Test-Python-Script.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-9838\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Test-Python-Script.png\" alt=\"Test Python Script\" width=\"362\" height=\"28\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Test Python Script<\/p>\n<\/div>\n<p>Let me explain the code in detailed explanation.<\/p>\n<ol>\n<li><b>#!\/usr\/bin\/python<\/b>: The default path for the Python interpreter (version 2.7 in most cases), this line must be the first line in every Python file.<\/li>\n<li><b># -*- coding: utf-8 -*-<\/b>: Here we set the default coding for the file, UTF-8 is the best if you want to support non-English languages, leave it like that.<\/li>\n<\/ol>\n<ol>\n<li><b>from gi.repository import Gtk<\/b>: Here we are importing the GTK 3 library to use it in our program.<\/li>\n<li>Class ourwindow(Gtk.Window): Here we are creating a new class, which is called \u201courwindow\u201d, we are also setting the class object type to a \u201cGtk.Window\u201d.<\/li>\n<li><b>def __init__(self)<\/b>: Nothing new, we\u2019re defining the main window components here.<\/li>\n<li><b>Gtk.Window.__init__(self, title=\u201dMy Hello World Program\u201d)<\/b>: We\u2019re using this line to set the \u201cMy Hello World Program\u201d title to \u201courwindow\u201d window, you may change the title if you like.<\/li>\n<li><b>Gtk.Window.set_default_size(self, 400,325)<\/b>: I don\u2019t think that this line need explanation, here we\u2019re setting the default width and height for our window.<\/li>\n<li><b>Gtk.Window.set_position(self, Gtk.WindowPosition.CENTER)<\/b>: Using this line, we\u2019ll be able to set the default position for the window, in this case, we set it to the center using the \u201cGtk.WindowPosition.CENTER\u201d parameter, if you want, you can change it to \u201cGtk.WindowPosition.MOUSE\u201d to open the window on the mouse pointer position.<\/li>\n<li><b>button1 = Gtk.Button(\u201cHello, World!\u201d)<\/b>: We created a new Gtk.Button, and we called it \u201cbutton1\u201d, the default text for the button is \u201cHello, World!\u201d, you may create any Gtk widget if you want.<\/li>\n<li><b>button1.connect(\u201cclicked\u201d, self.whenbutton1_clicked)<\/b>: Here we\u2019re linking the \u201cclicked\u201d signal with the \u201cwhenbutton1_clicked\u201d action, so that when the button is clicked, the \u201cwhenbutton1_clicked\u201d action is activated.<\/li>\n<li><b>self.add(button1)<\/b>: If we want our Gtk widgets to appear, we have to add them to the default window, this simple line adds the \u201cbutton1\u201d widget to the window, it\u2019s very necessary to do this.<\/li>\n<li><b>def whenbutton1_clicked(self, button)<\/b>: Now we\u2019re defining the \u201cwhenbutton1_clicked\u201d action here, we\u2019re defining what\u2019s going to happen when the \u201cbutton1\u201d widget is clicked, the \u201c(self, button)\u201d parameter is important in order to specific the signal parent object type.<\/li>\n<li><b>print \u201cHello, World!\u201d<\/b>: I don\u2019t have to explain more here.<\/li>\n<li><b>window = ourwindow()<\/b>: We have to create a new global variable and set it to ourwindow() class so that we can call it later using the GTK+ library.<\/li>\n<li><b>window.connect(\u201cdelete-event\u201d, Gtk.main_quit)<\/b>: Now we\u2019re connecting the \u201cdelete-event\u201d signal with the \u201cGtk.main_quit\u201d action, this is important in order to delete all the widgets after we close our program window automatically.<\/li>\n<li><b>window.show_all()<\/b>: Showing the window.<\/li>\n<li><b>Gtk.main()<\/b>: Running the Gtk library.<\/li>\n<\/ol>\n<p>That\u2019s it, easy isn\u2019t? And very functional if we want to create some large applications. For more information about creating GTK+ interfaces using the code-only way, you may visit the official documentation website at:<\/p>\n<p><a href=\"https:\/\/python-gtk-3-tutorial.readthedocs.org\/en\/latest\/\" target=\"_blank\" rel=\"nofollow noopener\">Python GTK3 Tutorials<\/a><\/p>\n<h4>The Glade Designer Way<\/h4>\n<p>Like I said in the beginning of the article, Glade is a very easy tool to create the interfaces we need for our programs, it\u2019s very famous among developers and many great applications interfaces were created using it. This way is called \u201cRapid applications development\u201d.<\/p>\n<p>You have to install Glade in order to start using it, on Debian\/Ubuntu\/Mint run:<\/p>\n<pre>$ sudo apt\u00ad-get install glade\r\n<\/pre>\n<p>On RedHat\/Fedora\/CentOS, run:<\/p>\n<pre># yum install glade\r\n<\/pre>\n<p>After you download and install the program, and after you run it, you will see the available Gtk widgets on the left, click on the \u201c<b>window<\/b>\u201d widget in order to create a new window.<\/p>\n<div id=\"attachment_9822\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Create-New-Widget.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-9822\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Create-New-Widget.png\" alt=\"Create New Widget\" width=\"228\" height=\"185\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create New Widget<\/p>\n<\/div>\n<p>You will notice that a new empty window is created.<\/p>\n<div id=\"attachment_9823\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/New-Window-Widget.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-9823\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/New-Window-Widget-620x339.png\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/New-Window-Widget-620x339.png 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/New-Window-Widget-1024x560.png 1024w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/New-Window-Widget.png 1169w\" alt=\"New Window Widget\" width=\"620\" height=\"339\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">New Window Widget<\/p>\n<\/div>\n<p>You can now add some widgets to it, on the left toolbar, click on the \u201c<b>button<\/b>\u201d widget, and click on the empty window in order to add the button to the window.<\/p>\n<div id=\"attachment_9824\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Add-Widget.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-9824\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Add-Widget.png\" alt=\"Add Widget\" width=\"244\" height=\"366\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Add Widget<\/p>\n<\/div>\n<p>You will notice that the button ID is \u201c<b>button1<\/b>\u201d, now refer to the Signals tab in the right toolbar, and search for the \u201c<b>clicked<\/b>\u201d signal and enter \u201c<b>button1_clicked<\/b>\u201d under it.<\/p>\n<div id=\"attachment_9825\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Button-Properties.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-9825\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Button-Properties-620x338.png\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Button-Properties-620x338.png 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Button-Properties-1024x559.png 1024w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Button-Properties.png 1176w\" alt=\"Glade Button Properties\" width=\"620\" height=\"338\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Button Properties<\/p>\n<\/div>\n<div id=\"attachment_9826\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Signals-Tab.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-9826\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Signals-Tab-620x300.png\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Signals-Tab-620x300.png 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Signals-Tab.png 641w\" alt=\"Glade Signals Tab\" width=\"620\" height=\"300\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Signals Tab<\/p>\n<\/div>\n<p>Now that we\u2019ve created our GUI, let\u2019s export it. Click on the \u201c<b>File<\/b>\u201d menu and choose \u201c<b>Save<\/b>\u201d, save the file in your home directory in the name \u201c<b>myprogram.glade<\/b>\u201d and exit.<\/p>\n<div id=\"attachment_9827\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Export-Widget-File.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-9827\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Export-Widget-File-580x450.png\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Export-Widget-File-580x450.png 580w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Export-Widget-File.png 919w\" alt=\"Glade Export Widget File\" width=\"580\" height=\"450\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Export Widget File<\/p>\n<\/div>\n<p>Now, create a new \u201c<b>test.py<\/b>\u201d file, and enter the following code inside it.<\/p>\n<pre>#!\/usr\/bin\/python\r\n# -*- coding: utf-8 -*-\r\n\r\nfrom gi.repository import Gtk\r\n\r\nclass Handler:\r\n    def button_1clicked(self, button):\r\n      print \"Hello, World!\"\r\n\r\nbuilder = Gtk.Builder()\r\nbuilder.add_from_file(\"myprogram.glade\")\r\nbuilder.connect_signals(Handler())\r\n\r\nournewbutton = builder.get_object(\"button1\")\r\nournewbutton.set_label(\"Hello, World!\")\r\n\r\nwindow = builder.get_object(\"window1\")\r\n\r\nwindow.connect(\"delete-event\", Gtk.main_quit)\r\nwindow.show_all()\r\nGtk.main()\r\n<\/pre>\n<div class=\"google-auto-placed ap_container\">\n<p>Save the file, give it 755 permissions like before, and run it using \u201c<b>.\/test.py<\/b>\u201d, and that\u2019s what you will get.<\/p>\n<pre># nano test.py\r\n# chmod 755 test.py\r\n# .\/test.py\r\n<\/pre>\n<div id=\"attachment_9828\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Hello-World-Window.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-9828\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/11\/Hello-World-Window.png\" alt=\"Hello World Window\" width=\"369\" height=\"227\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Hello World Window<\/p>\n<\/div>\n<p>Click on the button, and you will notice that the \u201c<b>Hello, World!<\/b>\u201d sentence is printed in the terminal.<\/p>\n<p>Now let\u2019s explain the new things:<\/p>\n<ol>\n<li><b>class Handler<\/b>: Here we\u2019re creating a class called \u201cHandler\u201d which will include the the definitions for the actions &amp; signals, we create for the GUI.<\/li>\n<li><b>builder = Gtk.Builder()<\/b>: We created a new global variable called \u201cbuilder\u201d which is a Gtk.Builder widget, this is important in order to import the .glade file.<\/li>\n<li><b>builder.add_from_file(\u201cmyprogram.glade\u201d)<\/b>: Here we\u2019re importing the \u201cmyprogram.glade\u201d file to use it as a default GUI for our program.<\/li>\n<li><b>builder.connect_signals(Handler())<\/b>: This line connects the .glade file with the handler class, so that the actions and signals that we define under the \u201cHandler\u201d class work fine when we run the program.<\/li>\n<li><b>ournewbutton = builder.get_object(\u201cbutton1\u201d)<\/b>: Now we\u2019re importing the \u201cbutton1\u201d object from the .glade file, we\u2019re also passing it to the global variable \u201cournewbutton\u201d to use it later in our program.<\/li>\n<li><b>ournewbutton.set_label(\u201cHello, World!\u201d)<\/b>: We used the \u201cset.label\u201d method to set the default button text to the \u201cHello, World!\u201d sentence.<\/li>\n<li><b>window = builder.get_object(\u201cwindow1\u201d)<\/b>: Here we called the \u201cwindow1\u201d object from the .glade file in order to show it later in the program.<\/li>\n<\/ol>\n<p>And that\u2019s it! You have successfully created your first program under Linux!<\/p>\n<p>Of course there are a lot more complicated things to do in order to create a real application that does something, that\u2019s why I recommend you to take a look into the GTK+ documentation and GObject API at:<\/p>\n<ol>\n<li><a href=\"https:\/\/developer.gnome.org\/gtk3\/stable\/\" target=\"_blank\" rel=\"nofollow noopener\">GTK+ Reference Manual<\/a><\/li>\n<li><a href=\"https:\/\/lazka.github.io\/pgi-docs\/\" target=\"_blank\" rel=\"nofollow noopener\">Python GObject API Reference<\/a><\/li>\n<li><a href=\"https:\/\/wiki.gnome.org\/action\/show\/Projects\/PyGObject?action=show&amp;redirect=PyGObject\" target=\"_blank\" rel=\"nofollow noopener\">PyGObject Reference<\/a><\/li>\n<\/ol>\n<p>Have you developed any application before under the Linux desktop? What programming language and tools have used to do it? What do you think about creating applications using Python &amp; GTK 3?<\/p>\n<h1 class=\"post-title\">Create More Advance GUI Applications Using PyGobject Tool in Linux \u2013 Part 2<\/h1>\n<p>We continue our series about creating GUI applications under the Linux desktop using\u00a0<b>PyGObject<\/b>, This is the second part of the series and today we\u2019ll be talking about creating more functional applications using some advanced widgets.<\/p>\n<div id=\"attachment_10093\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Gui-Applications-in-Linux-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10093\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Gui-Applications-in-Linux-2.png\" alt=\"Create Gui Applications in Linux\" width=\"600\" height=\"400\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create Gui Applications in Linux- Part 2<\/p>\n<\/div>\n<h4>Requirements<\/h4>\n<ol>\n<li><a href=\"https:\/\/www.tecmint.com\/create-gui-applications-in-linux\/\" target=\"_blank\" rel=\"noopener\">Create GUI Applications Under Linux Using PyGObject \u2013 Part 1<\/a><\/li>\n<\/ol>\n<p>In the previous article we said that there are two ways for creating GUI applications using\u00a0<b>PyGObject<\/b>: the\u00a0<b>code-only-way<\/b>\u00a0and the\u00a0<b>Glade<\/b>\u00a0designer way, but from now on, we\u2019ll only be explaining the\u00a0<b>Glade<\/b>\u00a0designer way since it\u2019s much easier for most users, you can learn the code-only-way by yourself using\u00a0<a href=\"https:\/\/python-gtk-3-tutorial.readthedocs.org\/en\/latest\" target=\"_blank\" rel=\"noopener\">python-gtk3-tutorial<\/a>.<\/p>\n<h3>Creating Advance GUI Applications in Linux<\/h3>\n<p><strong>1.<\/strong>\u00a0Let\u2019s start programming! Open your\u00a0<b>Glade<\/b>\u00a0designer from the applications menu.<\/p>\n<div id=\"attachment_10068\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-Designer.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10068\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-Designer-620x336.png\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-Designer-620x336.png 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-Designer-1024x556.png 1024w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-Designer.png 1360w\" alt=\"Glade Designer\" width=\"620\" height=\"336\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Glade Designer<\/p>\n<\/div>\n<p><strong>2.<\/strong>\u00a0Click on the \u201c<b>Window<\/b>\u201d button on the left sidebar in order to create a new one.<\/p>\n<div id=\"attachment_10069\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-New-Window.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10069\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-New-Window.png\" alt=\"Create New Window\" width=\"189\" height=\"148\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create New Window<\/p>\n<p><strong>3.<\/strong>\u00a0Click on the \u201c<b>Box<\/b>\u201d widget and release it on the empty window.<\/p>\n<div id=\"attachment_10070\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Select-Box-Widget.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10070\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Select-Box-Widget.png\" alt=\"Select Box Widget\" width=\"192\" height=\"170\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Select Box Widget<\/p>\n<\/div>\n<p><strong>4.<\/strong>\u00a0You will be prompted to enter the number of boxes you want, make it\u00a0<b>3<\/b>.<\/p>\n<div id=\"attachment_10071\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Boxes.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10071\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Boxes-620x335.png\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Boxes-620x335.png 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Boxes-1024x553.png 1024w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Boxes.png 1358w\" alt=\"Create Boxes\" width=\"620\" height=\"335\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create Boxes<\/p>\n<\/div>\n<p>And you\u2019ll see that the\u00a0<b>boxes<\/b>\u00a0are created, those boxes are important for us in order to be able to add more than just\u00a0<b>1<\/b>\u00a0widget in a window.<\/p>\n<p><strong>5.<\/strong>\u00a0Now click on the\u00a0<b>box<\/b>\u00a0widget, and change the orientation type from\u00a0<b>vertical<\/b>\u00a0to\u00a0<b>horizontal<\/b>.<\/p>\n<div id=\"attachment_10072\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Make-Box-Horizontal.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10072\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Make-Box-Horizontal.png\" alt=\"Make Box Horizontal\" width=\"595\" height=\"323\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Make Box Horizontal<\/p>\n<\/div>\n<p><strong>6.<\/strong>\u00a0In order to create a simple program, add a \u201c<b>Text Entry<\/b>\u201d, \u201c<b>Combo Box Text<\/b>\u201d and a \u201c<b>Button<\/b>\u201d widgets for each one of the boxes, you should have something like this.<\/p>\n<div id=\"attachment_10073\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Simple-Program.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10073\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Simple-Program-620x350.png\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Simple-Program-620x350.png 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Simple-Program-1024x578.png 1024w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Simple-Program.png 1360w\" alt=\"Create Simple Program\" width=\"620\" height=\"350\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create Simple Program<\/p>\n<\/div>\n<p><strong>7.<\/strong>\u00a0Now click on the \u201c<b>window1<\/b>\u201d widget from the right sidebar, and change its position to \u201c<b>Center<\/b>\u201c.<\/p>\n<div id=\"attachment_10074\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Make-Widget-Center.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10074\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Make-Widget-Center-427x450.png\" sizes=\"auto, (max-width: 427px) 100vw, 427px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Make-Widget-Center-427x450.png 427w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Make-Widget-Center.png 602w\" alt=\"Make Widget Center\" width=\"427\" height=\"450\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Make Widget Center<\/p>\n<\/div>\n<p>Scroll down to the \u201c<b>Appearance<\/b>\u201d section.. And add a title for the window \u201c<b>My Program<\/b>\u201c.<\/p>\n<div id=\"attachment_10075\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Widget-Title.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10075\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Widget-Title-332x450.png\" sizes=\"auto, (max-width: 332px) 100vw, 332px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Widget-Title-332x450.png 332w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Widget-Title.png 423w\" alt=\"Add Widget Title\" width=\"332\" height=\"450\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Add Widget Title<\/p>\n<\/div>\n<p><strong>8.<\/strong>\u00a0You can also choose an\u00a0<b>icon<\/b>\u00a0for the window by clicking on the \u201c<b>Icon Name<\/b>\u201d box.<\/p>\n<div id=\"attachment_10076\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Widget-Icon.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10076\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Widget-Icon-546x450.png\" sizes=\"auto, (max-width: 546px) 100vw, 546px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Widget-Icon-546x450.png 546w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Widget-Icon.png 611w\" alt=\"Set Widget Icon\" width=\"546\" height=\"450\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Set Widget Icon<\/p>\n<\/div>\n<p><strong>9.<\/strong>\u00a0You can also change the default\u00a0<b>height<\/b>\u00a0&amp;\u00a0<b>width<\/b>\u00a0for the application.. After all of that, you should have something like this.<\/p>\n<div id=\"attachment_10077\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Widget-Height-Width.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10077\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Widget-Height-Width.png\" alt=\"Set Widget Height Width\" width=\"591\" height=\"327\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Set Widget Height Width<\/p>\n<\/div>\n<p>In any program, one of the most important thing is to create a \u201c<b>About<\/b>\u201d window, to do this, first we\u2019ll have to change the normal button we created before into a stock button, look at the picture.<\/p>\n<div id=\"attachment_10078\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-About-Window.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10078\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-About-Window-620x350.png\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-About-Window-620x350.png 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-About-Window-1024x578.png 1024w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-About-Window.png 1360w\" alt=\"Create About Window\" width=\"620\" height=\"350\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create About Window<\/p>\n<\/div>\n<p><strong>10.<\/strong>\u00a0Now, we\u2019ll have to modify some signals in order to run specific actions when any event occur on our widgets. Click on the\u00a0<b>text entry<\/b>\u00a0widget, switch to the \u201c<b>Signals<\/b>\u201d tab in the right sidebar, search for \u201c<b>activated<\/b>\u201d and change its handler to \u201c<b>enter_button_clicked<\/b>\u201d, the \u201c<b>activated<\/b>\u201d signal is the default signal that is sent when the \u201c<b>Enter\u201d<\/b>\u00a0key is hit while focusing on the text entry widget.<\/p>\n<div id=\"attachment_10079\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Widget-Signals.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10079\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Widget-Signals-620x350.png\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Widget-Signals-620x350.png 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Widget-Signals-1024x578.png 1024w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Widget-Signals.png 1360w\" alt=\"Set Widget Signals\" width=\"620\" height=\"350\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Set Widget Signals<\/p>\n<\/div>\n<p>We\u2019ll have to add another handler for the \u201c<b>clicked<\/b>\u201d signal for our about button widget, click on it and change the \u201c<b>clicked<\/b>\u201d signal to \u201c<b>button_is_clicked<\/b>\u201c.<\/p>\n<div id=\"attachment_10080\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Widget-Handler.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10080\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Widget-Handler-620x350.png\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Widget-Handler-620x350.png 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Widget-Handler-1024x578.png 1024w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Widget-Handler.png 1360w\" alt=\"Add Widget Handler\" width=\"620\" height=\"350\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Add Widget Handler<\/p>\n<\/div>\n<p><strong>11.<\/strong>\u00a0Go to the \u201c<b>Common<\/b>\u201d tab and mark on \u201c<b>Has Focus<\/b>\u201d as it follows (To give the default focus for the about button instead of the entry).<\/p>\n<div id=\"attachment_10081\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Default-Focus.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10081\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Default-Focus-545x450.png\" sizes=\"auto, (max-width: 545px) 100vw, 545px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Default-Focus-545x450.png 545w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Default-Focus.png 589w\" alt=\"Set Default Focus\" width=\"545\" height=\"450\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Set Default Focus<\/p>\n<\/div>\n<p><strong>12.<\/strong>\u00a0Now from the left sidebar, create a new \u201c<b>About Dialog<\/b>\u201d window.<\/p>\n<div id=\"attachment_10082\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-About-Dialog.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10082\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-About-Dialog.png\" alt=\"Create About Dialog\" width=\"215\" height=\"143\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create About Dialog<\/p>\n<\/div>\n<p>And you will notice that the \u201c<b>About Dialog<\/b>\u201d window is created.<\/p>\n<div id=\"attachment_10083\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/About-Dialog.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10083\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/About-Dialog.png\" alt=\"About Dialog\" width=\"452\" height=\"294\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">About Dialog<\/p>\n<\/div>\n<p>Let\u2019s modify it.. Make sure that you insert the following settings for it from the right sidebar.<\/p>\n<div id=\"attachment_10084\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Program-Attributes.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10084\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Program-Attributes.png\" alt=\"Add Program Attributes\" width=\"591\" height=\"341\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Add Program Attributes<\/p>\n<\/div>\n<div id=\"attachment_10085\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Select-License.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10085\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Select-License.png\" alt=\"Select License\" width=\"584\" height=\"311\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Select License<\/p>\n<\/div>\n<div id=\"attachment_10086\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-About-Authors.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10086\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-About-Authors.png\" alt=\"Add About Authors\" width=\"579\" height=\"237\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Add About Authors<\/p>\n<\/div>\n<div id=\"attachment_10087\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Window-Appreance.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10087\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Set-Window-Appreance.png\" alt=\"Set Window Appreance\" width=\"586\" height=\"330\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Set Window Appreance<\/p>\n<\/div>\n<div id=\"attachment_10088\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Select-Appreance-Flags.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10088\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Select-Appreance-Flags.png\" alt=\"Select Appreance Flags\" width=\"593\" height=\"343\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Select Appreance Flags<\/p>\n<\/div>\n<p>After making above settings, you will get following about Window.<\/p>\n<div id=\"attachment_10089\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/My-Program-about-Window.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10089\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/My-Program-about-Window.png\" alt=\"My Program about Window\" width=\"444\" height=\"416\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">My Program about Window<\/p>\n<\/div>\n<p>In the above window, you will notice the empty space, but you can remove it by declining the number of boxes from 3 to 2 or you can add any widget to it if you want.<\/p>\n<div id=\"attachment_10090\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Change-Window-Boxes.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10090\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Change-Window-Boxes.png\" alt=\"Change Window Boxes\" width=\"590\" height=\"363\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Change Window Boxes<\/p>\n<\/div>\n<p><strong>13.<\/strong>\u00a0Now save the file in your home folder in the name \u201c<b>ui.glade<\/b>\u201d and open a text editor and enter the following code inside it.<\/p>\n<pre>#!\/usr\/bin\/python\r\n# -*- coding: utf-8 -*-\r\n\r\nfrom gi.repository import Gtk\r\nclass Handler:\r\n\r\n    def button_is_clicked(self, button):\r\n        ## The \".run()\" method is used to launch the about window.\r\n         ouraboutwindow.run()\r\n        ## This is just a workaround to enable closing the about window.\r\n         ouraboutwindow.hide()\r\n\r\n    def enter_button_clicked(self, button):\r\n        ## The \".get_text()\" method is used to grab the text from the entry box. The \"get_active_text()\" method is used to get the selected item from the Combo Box Text widget, here, we merged both texts together\".\r\n         print ourentry.get_text() + ourcomboboxtext.get_active_text()\r\n\r\n## Nothing new here.. We just imported the 'ui.glade' file.\r\nbuilder = Gtk.Builder()\r\nbuilder.add_from_file(\"ui.glade\")\r\nbuilder.connect_signals(Handler())\r\n\r\nournewbutton = builder.get_object(\"button1\")\r\n\r\nwindow = builder.get_object(\"window1\")\r\n\r\n## Here we imported the Combo Box widget in order to add some change on it.\r\nourcomboboxtext = builder.get_object(\"comboboxtext1\")\r\n\r\n## Here we defined a list called 'default_text' which will contain all the possible items in the Combo Box Text widget.\r\ndefault_text = [\" World \", \" Earth \", \" All \"]\r\n\r\n## This is a for loop that adds every single item of the 'default_text' list to the Combo Box Text widget using the '.append_text()' method.\r\nfor x in default_text:\r\n  ourcomboboxtext.append_text(x)\r\n\r\n## The '.set.active(n)' method is used to set the default item in the Combo Box Text widget, while n = the index of that item.\r\nourcomboboxtext.set_active(0)\r\nourentry = builder.get_object(\"entry1\")\r\n\r\n## This line doesn't need an explanation :D\r\nourentry.set_max_length(15)\r\n\r\n## Nor this do.\r\nourentry.set_placeholder_text(\"Enter A Text Here..\")\r\n\r\n## We just imported the about window here to the 'ouraboutwindow' global variable.\r\nouraboutwindow = builder.get_object(\"aboutdialog1\")\r\n\r\n## Give that developer a cookie !\r\nwindow.connect(\"delete-event\", Gtk.main_quit)\r\nwindow.show_all()\r\nGtk.main\r\n<\/pre>\n<div class=\"google-auto-placed ap_container\">\n<p>Save the file in your home directory under that name \u201c<b>myprogram.py<\/b>\u201d, and give it the execute permission and run it.<\/p>\n<pre>$ chmod 755 myprogram.py\r\n$ .\/myprogram.py<\/pre>\n<pre>This is what you will get, after running above script.<\/pre>\n<div id=\"attachment_10091\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/My-Program-Script.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10091\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/My-Program-Script.png\" alt=\"My Program Window\" width=\"406\" height=\"145\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">My Program Window<\/p>\n<\/div>\n<p>Enter a text in the entry box, hit the \u201c<b>Enter<\/b>\u201d key on the keyboard, and you will notice that the sentence is printed at the shell.<\/p>\n<div id=\"attachment_10092\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Box-Output-Text.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10092\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Box-Output-Text.png\" alt=\"Box Output Text\" width=\"448\" height=\"78\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Box Output Text<\/p>\n<\/div>\n<p>That\u2019s all for now, it\u2019s not a complete application, but I just wanted to show you how to link things together using\u00a0<b>PyGObject<\/b>, you can view all methods for all\u00a0<b>GTK<\/b>\u00a0widgets at\u00a0<a href=\"https:\/\/developer.gnome.org\/gtk3\/stable\/gtkobjects.html\" target=\"_blank\" rel=\"noopener\">gtkobjects<\/a>.<\/p>\n<p>Just learn the methods, create the widgets using\u00a0<b>Glade<\/b>, and connect the signals using the Python file, That\u2019s it! It\u2019s not hard at all my friend.<\/p>\n<p>We\u2019ll explain more new things about PyGObject in the next parts of the series, till then stay updated and don\u2019t forget to give us your comments about the article.<\/p>\n<h1 class=\"post-title\">Create Your Own \u2018Web Browser\u2019 and \u2018Desktop Recorder\u2019 Applications Using PyGobject \u2013 Part 3<\/h1>\n<p>This is the\u00a0<b>3rd<\/b>\u00a0part of the series about creating GUI applications under the Linux desktop using PyGObject. Today we\u2019ll talk about using some advanced Python modules &amp; libraries in our programs like \u2018<b>os<\/b>\u2018, \u2018<b>WebKit<\/b>\u2018, \u2018<b>requests<\/b>\u2018 and others, beside some other useful information for programming.<\/p>\n<div id=\"attachment_10240\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Gui-Applications-in-Linux-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10240\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Gui-Applications-in-Linux-3.png\" alt=\"Create Own Web Browser and Recorder \" width=\"600\" height=\"400\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create Own Web Browser and Recorder \u2013 Part 3<\/p>\n<\/div>\n<h4>Requirements<\/h4>\n<p>You must go through all these previous parts of the series from here, to continue further instructions on creating more advance applications:<\/p>\n<ol>\n<li><a href=\"https:\/\/www.tecmint.com\/create-gui-applications-in-linux\/\" target=\"_blank\" rel=\"noopener\">Create GUI Applications Under Linux Desktop Using PyGObject \u2013 Part 1<\/a><\/li>\n<li><a href=\"https:\/\/www.tecmint.com\/create-more-advance-gui-applications-in-linux\/\" target=\"_blank\" rel=\"noopener\">Creating Advance PyGobject Applications on Linux \u2013 Part 2<\/a><\/li>\n<\/ol>\n<p>Modules &amp; libraries in Python are very useful, instead of writing many sub-programs to do some complicated jobs which will take a lot of time and work, you can just import them ! Yes, just import the modules &amp; libraries you need to your program and you will be able to save a lot of time and effort to complete your program.<\/p>\n<p>There are many famous modules for Python, which you can find at\u00a0<a href=\"https:\/\/docs.python.org\/2\/py-modindex.html\" target=\"_blank\" rel=\"nofollow noopener\">Python Module Index<\/a>.<\/p>\n<p>You can import libraries as well for your Python program, from \u201c<b>gi.repository import Gtk<\/b>\u201d this line imports the GTK library into the Python program, there are many other libraries like Gdk, WebKit.. etc.<\/p>\n<h3>Creating Advance GUI Applications<\/h3>\n<p>Today, we\u2019ll create 2 programs:<\/p>\n<ol>\n<li>A simple web browser; which will use the WebKit library.<\/li>\n<li>A desktop recorder using the \u2018<a href=\"https:\/\/www.tecmint.com\/record-ubuntu-desktop-screen-using-avconv\/\" target=\"_blank\" rel=\"noopener\">avconv<\/a>\u2018 command; which will use the \u2018os\u2019 module from Python.<\/li>\n<\/ol>\n<p>I won\u2019t explain how to drag &amp; drop widgets in the\u00a0<b>Glade<\/b>\u00a0designer from now on, I will just tell you the name of the widgets that you need to create, additionally I will give you the\u00a0<b>.glade<\/b>\u00a0file for each program, and the Python file for sure.<\/p>\n<h4>Creating a Simple Web Browser<\/h4>\n<p>In order to create a web browser, we\u2019ll have to use the \u201c<b>WebKit<\/b>\u201d engine, which is an open-source rendering engine for the web, it\u2019s the same one which is used in\u00a0<b>Chrome<\/b>\/<b>Chromium<\/b>, for more info about it you may refer to the official\u00a0<a href=\"https:\/\/www.webkit.org\/\" target=\"_blank\" rel=\"noopener\">Webkit.org<\/a>\u00a0website.<\/p>\n<p>First, we\u2019ll have to create the GUI, open the\u00a0<b>Glade<\/b>\u00a0designer and add the following widgets. For more information on how to create widgets, follow the\u00a0<b>Part 1<\/b>\u00a0and\u00a0<b>Part 2<\/b>\u00a0of this series (links given above).<\/p>\n<ol>\n<li>Create \u2018window1\u2019 widget.<\/li>\n<li>Create \u2018box1\u2019 and \u2018box2\u2019 widget.<\/li>\n<li>Create \u2018button1\u2019 and \u2018button2\u2019 widget.<\/li>\n<li>Create \u2018entry1\u2019 widget.<\/li>\n<li>Create \u2018scrolledwindow1\u2019 widget.<\/li>\n<\/ol>\n<div id=\"attachment_10234\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Widgets.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10234\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Add-Widgets.png\" alt=\"Add Widgets\" width=\"390\" height=\"193\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Add Widgets<\/p>\n<\/div>\n<p>After creating widgets, you will get the following interface.<\/p>\n<div id=\"attachment_10235\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-Interface.jpeg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10235\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-Interface-620x348.jpeg\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-Interface-620x348.jpeg 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-Interface-1024x575.jpeg 1024w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-Interface.jpeg 1366w\" alt=\"Glade Interface\" width=\"620\" height=\"348\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Glade Interface<\/p>\n<\/div>\n<p>There\u2019s nothing new, except the \u201c<b>Scrolled Window<\/b>\u201d widget; this widget is important in order to allow the\u00a0<b>WebKit<\/b>engine to be implanted inside it, using the \u201c<b>Scrolled Window<\/b>\u201d widget you will also be able to scroll horizontally and vertically while you browse the websites.<\/p>\n<p>You will have now to add \u201c<b>backbutton_clicked<\/b>\u201d handler to the\u00a0<b>Back<\/b>\u00a0button \u201c<b>clicked<\/b>\u201d signal, \u201c<b>refreshbutton_clicked<\/b>\u201d handler to the Refresh button \u201c<b>clicked signal<\/b>\u201d and \u201c<b>enterkey_clicked<\/b>\u201d handler to the \u201c<b>activated<\/b>\u201d signal for the entry.<\/p>\n<p>The complete\u00a0<b>.glade<\/b>\u00a0file for the interface is here.<\/p>\n<pre>&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;!-- Generated with glade 3.16.1 --&gt;\r\n&lt;interface&gt;\r\n\u00a0 &lt;requires lib=\"gtk+\" version=\"3.10\"\/&gt;\r\n\u00a0 &lt;object class=\"GtkWindow\" id=\"window1\"&gt;\r\n\u00a0\u00a0\u00a0 &lt;property name=\"can_focus\"&gt;False&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0 &lt;property name=\"title\" translatable=\"yes\"&gt;Our Simple Browser&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0 &lt;property name=\"window_position\"&gt;center&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0 &lt;property name=\"default_width\"&gt;1000&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0 &lt;property name=\"default_height\"&gt;600&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0 &lt;property name=\"icon_name\"&gt;applications-internet&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0 &lt;child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;object class=\"GtkBox\" id=\"box1\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"visible\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"can_focus\"&gt;False&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"orientation\"&gt;vertical&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;object class=\"GtkBox\" id=\"box2\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"visible\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"can_focus\"&gt;False&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;object class=\"GtkButton\" id=\"button1\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"label\"&gt;gtk-go-back&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"visible\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"can_focus\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"receives_default\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"relief\"&gt;half&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"use_stock\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"always_show_image\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;signal name=\"clicked\" handler=\"backbutton_clicked\" swapped=\"no\"\/&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/object&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;packing&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"expand\"&gt;False&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"fill\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"position\"&gt;0&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/packing&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;object class=\"GtkButton\" id=\"button2\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"label\"&gt;gtk-refresh&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"visible\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"can_focus\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"receives_default\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"relief\"&gt;half&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"use_stock\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"always_show_image\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;signal name=\"clicked\" handler=\"refreshbutton_clicked\" swapped=\"no\"\/&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/object&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;packing&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"expand\"&gt;False&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"fill\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"position\"&gt;1&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/packing&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;object class=\"GtkEntry\" id=\"entry1\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"visible\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"can_focus\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;signal name=\"activate\" handler=\"enterkey_clicked\" swapped=\"no\"\/&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/object&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;packing&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"expand\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"fill\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"position\"&gt;2&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/packing&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/object&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;packing&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"expand\"&gt;False&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"fill\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"position\"&gt;0&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/packing&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;object class=\"GtkScrolledWindow\" id=\"scrolledwindow1\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"visible\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"can_focus\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"hscrollbar_policy\"&gt;always&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"shadow_type\"&gt;in&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;placeholder\/&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/object&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;packing&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"expand\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"fill\"&gt;True&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;property name=\"position\"&gt;1&lt;\/property&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/packing&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/child&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/object&gt;\r\n\u00a0\u00a0\u00a0 &lt;\/child&gt;\r\n\u00a0 &lt;\/object&gt;\r\n&lt;\/interface&gt;<\/pre>\n<p>Now copy the above code and paste it in the \u201c<b>ui.glade<\/b>\u201d file in your home folder. Now create a new file called \u201c<b>mywebbrowser.py<\/b>\u201d and enter the following code inside it, all the explanation is in the comments.<\/p>\n<pre>#!\/usr\/bin\/python \r\n# -*- coding: utf-8 -*- \r\n\r\n## Here we imported both Gtk library and the WebKit engine. \r\nfrom gi.repository import Gtk, WebKit \r\n\r\nclass Handler: \r\n  \r\n  def backbutton_clicked(self, button): \r\n  ## When the user clicks on the Back button, the '.go_back()' method is activated, which will send the user to the previous page automatically, this method is part from the WebKit engine. \r\n    browserholder.go_back() \r\n\r\n  def refreshbutton_clicked(self, button): \r\n  ## Same thing here, the '.reload()' method is activated when the 'Refresh' button is clicked. \r\n    browserholder.reload() \r\n    \r\n  def enterkey_clicked(self, button): \r\n  ## To load the URL automatically when the \"Enter\" key is hit from the keyboard while focusing on the entry box, we have to use the '.load_uri()' method and grab the URL from the entry box. \r\n    browserholder.load_uri(urlentry.get_text()) \r\n    \r\n## Nothing new here.. We just imported the 'ui.glade' file. \r\nbuilder = Gtk.Builder() \r\nbuilder.add_from_file(\"ui.glade\") \r\nbuilder.connect_signals(Handler()) \r\n\r\nwindow = builder.get_object(\"window1\") \r\n\r\n## Here's the new part.. We created a global object called 'browserholder' which will contain the WebKit rendering engine, and we set it to 'WebKit.WebView()' which is the default thing to do if you want to add a WebKit engine to your program. \r\nbrowserholder = WebKit.WebView() \r\n\r\n## To disallow editing the webpage. \r\nbrowserholder.set_editable(False) \r\n\r\n## The default URL to be loaded, we used the 'load_uri()' method. \r\nbrowserholder.load_uri(\"https:\/\/tecmint.com\") \r\n\r\nurlentry = builder.get_object(\"entry1\") \r\nurlentry.set_text(\"https:\/\/tecmint.com\") \r\n\r\n## Here we imported the scrolledwindow1 object from the ui.glade file. \r\nscrolled_window = builder.get_object(\"scrolledwindow1\") \r\n\r\n## We used the '.add()' method to add the 'browserholder' object to the scrolled window, which contains our WebKit browser. \r\nscrolled_window.add(browserholder) \r\n\r\n## And finally, we showed the 'browserholder' object using the '.show()' method. \r\nbrowserholder.show() \r\n \r\n## Give that developer a cookie ! \r\nwindow.connect(\"delete-event\", Gtk.main_quit) \r\nwindow.show_all() \r\nGtk.main()\r\n<\/pre>\n<p>Save the file, and run it.<\/p>\n<pre>$ chmod 755 mywebbrowser.py\r\n$ .\/mywebbrowser.py\r\n<\/pre>\n<p>And this is what you will get.<\/p>\n<div id=\"attachment_10236\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Your-Own-Web-Browser.jpeg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10236\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Your-Own-Web-Browser-620x392.jpeg\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Your-Own-Web-Browser-620x392.jpeg 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Your-Own-Web-Browser-1024x648.jpeg 1024w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Your-Own-Web-Browser.jpeg 1037w\" alt=\"Create Own Web Browser\" width=\"620\" height=\"392\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create Own Web Browser<\/p>\n<\/div>\n<p>You may refer for the\u00a0<b>WebKitGtk<\/b>\u00a0official documentation in order to discover more options.<\/p>\n<h4>Creating a Simple Desktop Recorder<\/h4>\n<p>In this section, we\u2019ll learn how to run local system commands or shell scripts from the Python file using the \u2018<b>os<\/b>\u2018 module, which will help us to create a simple screen recorder for the desktop using the \u2018<b>avconv<\/b>\u2018 command.<\/p>\n<p>Open the Glade designer, and create the following widgets:<\/p>\n<ol>\n<li>Create \u2018window1\u2019 widget.<\/li>\n<li>Create \u2018box1\u2019 widget.<\/li>\n<li>Create \u2018button1\u2019, \u2018button2\u2019 and \u2018button3\u2019 widgets.<\/li>\n<li>Create \u2018entry1\u2019 widget.<\/li>\n<\/ol>\n<div id=\"attachment_10237\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Widgets.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10237\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Widgets-420x450.png\" sizes=\"auto, (max-width: 420px) 100vw, 420px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Widgets-420x450.png 420w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Widgets.png 549w\" alt=\"Create Widgets\" width=\"420\" height=\"450\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create Widgets<\/p>\n<\/div>\n<p>After creating above said widgets, you will get below interface.<\/p>\n<div id=\"attachment_10238\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-UI-Interface.jpeg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10238\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-UI-Interface-620x348.jpeg\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-UI-Interface-620x348.jpeg 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-UI-Interface-1024x575.jpeg 1024w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Glade-UI-Interface.jpeg 1366w\" alt=\"Glade UI Interface\" width=\"620\" height=\"348\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Glade UI Interface<\/p>\n<\/div>\n<p>Here\u2019s the complete\u00a0<b>ui.glade<\/b>\u00a0file.<\/p>\n<pre>&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt; \r\n&lt;!-- Generated with glade 3.16.1 --&gt; \r\n&lt;interface&gt; \r\n  &lt;requires lib=\"gtk+\" version=\"3.10\"\/&gt; \r\n  &lt;object class=\"GtkWindow\" id=\"window1\"&gt; \r\n    &lt;property name=\"can_focus\"&gt;False&lt;\/property&gt; \r\n    &lt;property name=\"title\" translatable=\"yes\"&gt;Our Simple Recorder&lt;\/property&gt; \r\n    &lt;property name=\"window_position\"&gt;center&lt;\/property&gt; \r\n    &lt;property name=\"default_width\"&gt;300&lt;\/property&gt; \r\n    &lt;property name=\"default_height\"&gt;30&lt;\/property&gt; \r\n    &lt;property name=\"icon_name\"&gt;applications-multimedia&lt;\/property&gt; \r\n    &lt;child&gt; \r\n      &lt;object class=\"GtkBox\" id=\"box1\"&gt; \r\n        &lt;property name=\"visible\"&gt;True&lt;\/property&gt; \r\n        &lt;property name=\"can_focus\"&gt;False&lt;\/property&gt; \r\n        &lt;child&gt; \r\n          &lt;object class=\"GtkEntry\" id=\"entry1\"&gt; \r\n            &lt;property name=\"visible\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"can_focus\"&gt;True&lt;\/property&gt; \r\n          &lt;\/object&gt; \r\n          &lt;packing&gt; \r\n            &lt;property name=\"expand\"&gt;False&lt;\/property&gt; \r\n            &lt;property name=\"fill\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"position\"&gt;0&lt;\/property&gt; \r\n          &lt;\/packing&gt; \r\n        &lt;\/child&gt; \r\n        &lt;child&gt; \r\n          &lt;object class=\"GtkButton\" id=\"button1\"&gt; \r\n            &lt;property name=\"label\"&gt;gtk-media-record&lt;\/property&gt; \r\n            &lt;property name=\"visible\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"can_focus\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"receives_default\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"use_stock\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"always_show_image\"&gt;True&lt;\/property&gt; \r\n            &lt;signal name=\"clicked\" handler=\"recordbutton\" swapped=\"no\"\/&gt; \r\n          &lt;\/object&gt; \r\n          &lt;packing&gt; \r\n            &lt;property name=\"expand\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"fill\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"position\"&gt;1&lt;\/property&gt; \r\n          &lt;\/packing&gt; \r\n        &lt;\/child&gt; \r\n        &lt;child&gt; \r\n          &lt;object class=\"GtkButton\" id=\"button2\"&gt; \r\n            &lt;property name=\"label\"&gt;gtk-media-stop&lt;\/property&gt; \r\n            &lt;property name=\"visible\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"can_focus\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"receives_default\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"use_stock\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"always_show_image\"&gt;True&lt;\/property&gt; \r\n            &lt;signal name=\"clicked\" handler=\"stopbutton\" swapped=\"no\"\/&gt; \r\n          &lt;\/object&gt; \r\n          &lt;packing&gt; \r\n            &lt;property name=\"expand\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"fill\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"position\"&gt;2&lt;\/property&gt; \r\n          &lt;\/packing&gt; \r\n        &lt;\/child&gt; \r\n        &lt;child&gt; \r\n          &lt;object class=\"GtkButton\" id=\"button3\"&gt; \r\n            &lt;property name=\"label\"&gt;gtk-media-play&lt;\/property&gt; \r\n            &lt;property name=\"visible\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"can_focus\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"receives_default\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"use_stock\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"always_show_image\"&gt;True&lt;\/property&gt; \r\n            &lt;signal name=\"clicked\" handler=\"playbutton\" swapped=\"no\"\/&gt; \r\n          &lt;\/object&gt; \r\n          &lt;packing&gt; \r\n            &lt;property name=\"expand\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"fill\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"position\"&gt;3&lt;\/property&gt; \r\n          &lt;\/packing&gt; \r\n        &lt;\/child&gt; \r\n      &lt;\/object&gt; \r\n    &lt;\/child&gt; \r\n  &lt;\/object&gt; \r\n&lt;\/interface&gt;\r\n<\/pre>\n<p>As usual, copy the above code and paste it in the file \u201c<b>ui.glade<\/b>\u201d in your home directory, create a new \u201c<b>myrecorder.py<\/b>\u201d file and enter the following code inside it (Every new line is explained in the comments).<\/p>\n<pre>#!\/usr\/bin\/python \r\n# -*- coding: utf-8 -*- \r\n\r\n## Here we imported both Gtk library and the os module. \r\nfrom gi.repository import Gtk \r\nimport os \r\n        \r\nclass Handler: \r\n  def recordbutton(self, button): \r\n    ## We defined a variable: 'filepathandname', we assigned the bash local variable '$HOME' to it + \"\/\" + the file name from the text entry box. \r\n    filepathandname = os.environ[\"HOME\"] + \"\/\" + entry.get_text() \r\n    \r\n    ## Here exported the 'filepathandname' variable from Python to the 'filename' variable in the shell. \r\n    os.environ[\"filename\"] = filepathandname \r\n    \r\n    ## Using 'os.system(COMMAND)' we can execute any shell command or shell script, here we executed the 'avconv' command to record the desktop video &amp; audio. \r\n    os.system(\"avconv -f x11grab -r 25 -s `xdpyinfo | grep 'dimensions:'|awk '{print $2}'` -i :0.0 -vcodec libx264 -threads 4 $filename -y &amp; \") \r\n    \r\n    \r\n  def stopbutton(self, button): \r\n    ## Run the 'killall avconv' command when the stop button is clicked. \r\n    os.system(\"killall avconv\") \r\n    \r\n  def playbutton(self, button): \r\n  ## Run the 'avplay' command in the shell to play the recorded file when the play button is clicked. \r\n    os.system(\"avplay $filename &amp;\") \r\n    \r\n    \r\n## Nothing new here.. We just imported the 'ui.glade' file. \r\nbuilder = Gtk.Builder() \r\nbuilder.add_from_file(\"ui.glade\") \r\nbuilder.connect_signals(Handler()) \r\n\r\nwindow = builder.get_object(\"window1\") \r\nentry = builder.get_object(\"entry1\") \r\nentry.set_text(\"myrecording-file.avi\") \r\n\r\n## Give that developer a cookie ! \r\nwindow.connect(\"delete-event\", Gtk.main_quit) \r\nwindow.show_all() \r\nGtk.main()\r\n<\/pre>\n<p>Now run the file by applying the following commands in the terminal.<\/p>\n<pre>$ chmod 755 myrecorder.py\r\n$ .\/myrecorder.py\r\n<\/pre>\n<p>And you got your first desktop recorder.<\/p>\n<div id=\"attachment_10239\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Own-Desktop-Recorder.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10239\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Own-Desktop-Recorder.png\" alt=\"Create Desktop Recorder\" width=\"499\" height=\"182\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create Desktop Recorder<\/p>\n<\/div>\n<p>You can find more information about the \u2018<b>os<\/b>\u2018 module at\u00a0<a href=\"https:\/\/docs.python.org\/2\/library\/os.html\" target=\"_blank\" rel=\"nofollow noopener\">Python OS Library<\/a>.<\/p>\n<p>And that\u2019s it, creating applications for the Linux desktop isn\u2019t hard using\u00a0<b>PyGObject<\/b>, you just have to create the GUI, import some modules and link the Python file with the GUI, nothing more, nothing less. There are many useful tutorials about doing this in the\u00a0<a href=\"https:\/\/wiki.gnome.org\/action\/show\/Projects\/PyGObject?action=show&amp;redirect=PyGObject\" target=\"_blank\" rel=\"noopener\">PyGObject<\/a>\u00a0website:<\/p>\n<p>Have you tried creating applications using PyGObject? What do you think about doing so? What applications have you developed before?<\/p>\n<h1 class=\"post-title\">Package PyGObject Applications and Programs as \u201c.deb\u201d Package for the Linux Desktop \u2013 Part 4<\/h1>\n<p>We continue the\u00a0<b>PyGObject<\/b>\u00a0programming series with you on the Linux desktop, in the\u00a0<b>4th<\/b>\u00a0part of the series we\u2019ll explain how to package the programs and applications that we created for the Linux desktop using PyGObject as a Debian package.<\/p>\n<div id=\"attachment_10425\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Package-Applications-as-Deb-Package.jpeg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10425\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Package-Applications-as-Deb-Package.jpeg\" alt=\"Packaging Applications as Deb Package\" width=\"600\" height=\"400\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Packaging Applications as Deb Package<\/p>\n<\/div>\n<p>Debian packages (<b>.deb<\/b>) are the most used format to install programs under Linux, the \u201c<b>dpkg<\/b>\u201d system which deals with\u00a0<b>.deb<\/b>\u00a0packages is the default on all Debian-based Linux distributions like Ubuntu and Linux Mint. That\u2019s why we\u2019ll be only explaining how to package our programs for Debian.<\/p>\n<h3>Create a Debian Package from your PyGObject Applications<\/h3>\n<p>First, you should have some basic knowledge about creating Debian packages, this following guide will help you a lot.<\/p>\n<ol>\n<li><a href=\"https:\/\/wiki.debian.org\/IntroDebianPackaging\" target=\"_blank\" rel=\"nofollow noopener\">Introduction to Debian Packaging<\/a><\/li>\n<\/ol>\n<p>In brief, if you have project called \u201c<b>myprogram<\/b>\u201d it must contain the following files and folders so that you can package it.<\/p>\n<div id=\"attachment_10420\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Deb-Package.jpeg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10420\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Deb-Package-620x425.jpeg\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Deb-Package-620x425.jpeg 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Create-Deb-Package.jpeg 906w\" alt=\"Create Deb Package\" width=\"620\" height=\"425\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Create Deb Package<\/p>\n<\/div>\n<ol>\n<li><b>debian<\/b>\u00a0(Folder): This folder includes all information about the Debian package divided to many sub-files.<\/li>\n<li><b>po<\/b>\u00a0(Folder): The po folder includes the translation files for the program (We\u2019ll explain it in part 5).<\/li>\n<li><b>myprogram<\/b>\u00a0(File): This is the Python file we created using PyGObject, it\u2019s the main file of the project.<\/li>\n<li><b>ui.glade<\/b>\u00a0(File): The graphical user interface file.. If you created the application\u2019s interface using Glade, you must include this file in<br \/>\nyour project.<\/li>\n<li><b>bMyprogram.desktop<\/b>\u00a0(File): This is the responsible file for showing the application in the applications menu.<\/li>\n<li><b>setup.py<\/b>\u00a0(File): This file is the responsible for installing any Python program into the local system, it\u2019s very important in any Python program, it has many other ways of usage as well.<\/li>\n<\/ol>\n<p>Of course.. There are many other files and folders that you can include in your project (in fact you can include anything you want) but those are the basic ones.<\/p>\n<p>Now, let\u2019s start packaging a project. Create a new folder called \u201c<b>myprogram<\/b>\u201d, create a file called \u201c<b>myprogram<\/b>\u201d and add the following code to it.<\/p>\n<pre>#!\/usr\/bin\/python \r\n# -*- coding: utf-8 -*- \r\n\r\n## Replace your name and email. \r\n# My Name &lt;myemail@email.com&gt; \r\n\r\n## Here you must add the license of the file, replace \"MyProgram\" with your program name. \r\n# License: \r\n#    MyProgram is free software: you can redistribute it and\/or modify \r\n#    it under the terms of the GNU General Public License as published by \r\n#    the Free Software Foundation, either version 3 of the License, or \r\n#    (at your option) any later version. \r\n# \r\n#    MyProgram is distributed in the hope that it will be useful, \r\n#    but WITHOUT ANY WARRANTY; without even the implied warranty of \r\n#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the \r\n#    GNU General Public License for more details. \r\n# \r\n#    You should have received a copy of the GNU General Public License \r\n#    along with MyProgram.  If not, see &lt;http:\/\/www.gnu.org\/licenses\/&gt;. \r\n\r\nfrom gi.repository import Gtk \r\nimport os \r\n\r\nclass Handler: \r\n  \r\n  def openterminal(self, button): \r\n    ## When the user clicks on the first button, the terminal will be opened. \r\n    os.system(\"x-terminal-emulator \") \r\n  \r\n  def closeprogram(self, button): \r\n    Gtk.main_quit() \r\n    \r\n# Nothing new here.. We just imported the 'ui.glade' file. \r\nbuilder = Gtk.Builder() \r\nbuilder.add_from_file(\"\/usr\/lib\/myprogram\/ui.glade\") \r\nbuilder.connect_signals(Handler()) \r\nwindow = builder.get_object(\"window1\") \r\nwindow.connect(\"delete-event\", Gtk.main_quit) \r\nwindow.show_all() \r\nGtk.main()\r\n<\/pre>\n<p>Create a\u00a0<b>ui.glade<\/b>\u00a0file and fill it up with this code.<\/p>\n<pre>&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt; \r\n&lt;!-- Generated with glade 3.16.1 --&gt; \r\n&lt;interface&gt; \r\n  &lt;requires lib=\"gtk+\" version=\"3.10\"\/&gt; \r\n  &lt;object class=\"GtkWindow\" id=\"window1\"&gt; \r\n    &lt;property name=\"can_focus\"&gt;False&lt;\/property&gt; \r\n    &lt;property name=\"title\" translatable=\"yes\"&gt;My Program&lt;\/property&gt; \r\n    &lt;property name=\"window_position\"&gt;center&lt;\/property&gt; \r\n    &lt;property name=\"icon_name\"&gt;applications-utilities&lt;\/property&gt; \r\n    &lt;property name=\"gravity\"&gt;center&lt;\/property&gt; \r\n    &lt;child&gt; \r\n      &lt;object class=\"GtkBox\" id=\"box1\"&gt; \r\n        &lt;property name=\"visible\"&gt;True&lt;\/property&gt; \r\n        &lt;property name=\"can_focus\"&gt;False&lt;\/property&gt; \r\n        &lt;property name=\"margin_left\"&gt;5&lt;\/property&gt; \r\n        &lt;property name=\"margin_right\"&gt;5&lt;\/property&gt; \r\n        &lt;property name=\"margin_top\"&gt;5&lt;\/property&gt; \r\n        &lt;property name=\"margin_bottom\"&gt;5&lt;\/property&gt; \r\n        &lt;property name=\"orientation\"&gt;vertical&lt;\/property&gt; \r\n        &lt;property name=\"homogeneous\"&gt;True&lt;\/property&gt; \r\n        &lt;child&gt; \r\n          &lt;object class=\"GtkLabel\" id=\"label1\"&gt; \r\n            &lt;property name=\"visible\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"can_focus\"&gt;False&lt;\/property&gt; \r\n            &lt;property name=\"label\" translatable=\"yes\"&gt;Welcome to this Test Program !&lt;\/property&gt; \r\n          &lt;\/object&gt; \r\n          &lt;packing&gt; \r\n            &lt;property name=\"expand\"&gt;False&lt;\/property&gt; \r\n            &lt;property name=\"fill\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"position\"&gt;0&lt;\/property&gt; \r\n          &lt;\/packing&gt; \r\n        &lt;\/child&gt; \r\n        &lt;child&gt; \r\n          &lt;object class=\"GtkButton\" id=\"button2\"&gt; \r\n            &lt;property name=\"label\" translatable=\"yes\"&gt;Click on me to open the Terminal&lt;\/property&gt; \r\n            &lt;property name=\"visible\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"can_focus\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"receives_default\"&gt;True&lt;\/property&gt; \r\n            &lt;signal name=\"clicked\" handler=\"openterminal\" swapped=\"no\"\/&gt; \r\n          &lt;\/object&gt; \r\n          &lt;packing&gt; \r\n            &lt;property name=\"expand\"&gt;False&lt;\/property&gt; \r\n            &lt;property name=\"fill\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"position\"&gt;1&lt;\/property&gt; \r\n          &lt;\/packing&gt; \r\n        &lt;\/child&gt; \r\n        &lt;child&gt; \r\n          &lt;object class=\"GtkButton\" id=\"button3\"&gt; \r\n            &lt;property name=\"label\"&gt;gtk-preferences&lt;\/property&gt; \r\n            &lt;property name=\"visible\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"can_focus\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"receives_default\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"use_stock\"&gt;True&lt;\/property&gt; \r\n          &lt;\/object&gt; \r\n          &lt;packing&gt; \r\n            &lt;property name=\"expand\"&gt;False&lt;\/property&gt; \r\n            &lt;property name=\"fill\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"position\"&gt;2&lt;\/property&gt; \r\n          &lt;\/packing&gt; \r\n        &lt;\/child&gt; \r\n        &lt;child&gt; \r\n          &lt;object class=\"GtkButton\" id=\"button4\"&gt; \r\n            &lt;property name=\"label\"&gt;gtk-about&lt;\/property&gt; \r\n            &lt;property name=\"visible\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"can_focus\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"receives_default\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"use_stock\"&gt;True&lt;\/property&gt; \r\n          &lt;\/object&gt; \r\n          &lt;packing&gt; \r\n            &lt;property name=\"expand\"&gt;False&lt;\/property&gt; \r\n            &lt;property name=\"fill\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"position\"&gt;3&lt;\/property&gt; \r\n          &lt;\/packing&gt; \r\n        &lt;\/child&gt; \r\n        &lt;child&gt; \r\n          &lt;object class=\"GtkButton\" id=\"button1\"&gt; \r\n            &lt;property name=\"label\"&gt;gtk-close&lt;\/property&gt; \r\n            &lt;property name=\"visible\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"can_focus\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"receives_default\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"use_stock\"&gt;True&lt;\/property&gt; \r\n            &lt;signal name=\"clicked\" handler=\"closeprogram\" swapped=\"no\"\/&gt; \r\n          &lt;\/object&gt; \r\n          &lt;packing&gt; \r\n            &lt;property name=\"expand\"&gt;False&lt;\/property&gt; \r\n            &lt;property name=\"fill\"&gt;True&lt;\/property&gt; \r\n            &lt;property name=\"position\"&gt;4&lt;\/property&gt; \r\n          &lt;\/packing&gt; \r\n        &lt;\/child&gt; \r\n      &lt;\/object&gt; \r\n    &lt;\/child&gt; \r\n  &lt;\/object&gt; \r\n&lt;\/interface&gt;<\/pre>\n<p>There\u2019s nothing new until now.. We just created a Python file and its interface file. Now create a \u201c<b>setup.py<\/b>\u201d file in the same folder, and add the following code to it, every line is explained in the comments.<\/p>\n<pre># 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 \r\nfrom distutils.core import setup \r\n\r\nsetup(name = \"<b>myprogram<\/b>\", # Name of the program. \r\n      version = \"<b>1.0<\/b>\", # Version of the program. \r\n      description = \"<b>An easy-to-use web interface to create &amp; share pastes easily<\/b>\", # You don't need any help here. \r\n      author = \"<b>TecMint<\/b>\", # Nor here. \r\n      author_email = \"<b>myemail@mail.com<\/b>\",# Nor here :D \r\n      url = \"<b>http:\/\/example.com<\/b>\", # If you have a website for you program.. put it here. \r\n      license='<b>GPLv3<\/b>', # The license of the program. \r\n      scripts=['<b>myprogram<\/b>'], # 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. \r\n\r\n# 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 \r\n      data_files = [ (\"<b>lib\/myprogram<\/b>\", [\"ui.glade\"]), # This is going to install the \"ui.glade\" file under the \/usr\/lib\/myprogram path. \r\n                     (\"<b>share\/applications<\/b>\", [\"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. \r\n<\/pre>\n<p>Now create a \u201c<b>myprogram.desktop<\/b>\u201d file in the same folder, and add the following code, it\u2019s explained as well in the comments.<\/p>\n<pre># 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 \r\n[Desktop Entry] \r\n# The default name of the program. \r\nName=My Program \r\n# 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. \r\nName[ar]=\u0628\u0631\u0646\u0627\u0645\u062c\u064a \r\n# Description of the file. \r\nComment=A simple test program developed by me. \r\n# Description of the file in Arabic. \r\nComment[ar]=\u0628\u0631\u0646\u0627\u0645\u062c \u062a\u062c\u0631\u064a\u0628\u064a \u0628\u0633\u064a\u0637 \u062a\u0645 \u062a\u0637\u0648\u064a\u0631\u0647 \u0628\u0648\u0627\u0633\u0637\u062a\u064a. \r\n# 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 \r\nExec=myprogram \r\n# Do you want to run your program from the terminal? \r\nTerminal=false \r\n# Leave this like that. \r\nType=Application \r\n# 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. \r\nIcon=system \r\n# The category of the file, you can view the available categories from the freedesktop website.\r\nCategories=GNOME;GTK;Utility; \r\nStartupNotify=false \r\n<\/pre>\n<div class=\"google-auto-placed ap_container\">\n<p>We\u2019re almost done here now.. We just have to create some small files under the \u201c<b>debian<\/b>\u201d folder in order to provide information about our package for the \u201c<b>dpkg<\/b>\u201d system.<\/p>\n<p>Open the \u201c<b>debian<\/b>\u201d folder, and create a the following files.<\/p>\n<pre>control\r\ncompat\r\nchangelog\r\nrules\r\n<\/pre>\n<div id=\"attachment_10421\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Project-Files.jpeg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10421\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Project-Files-620x426.jpeg\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Project-Files-620x426.jpeg 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Project-Files.jpeg 910w\" alt=\"Project Files For Deb Package\" width=\"620\" height=\"426\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Project Files For Deb Package<\/p>\n<\/div>\n<p><b>control<\/b>: This file provides the basic information about the Debian package, for more details, please visit\u00a0<a href=\"https:\/\/www.debian.org\/doc\/debian-policy\/ch-controlfields.html\" target=\"_blank\" rel=\"nofollow noopener\">Debian Package Control Fields<\/a>.<\/p>\n<pre>Source: myprogram\r\nMaintainer: My Name &lt;myemail@email.com&gt; \r\nSection: utils \r\nPriority: optional \r\nStandards-Version: 3.9.2 \r\nBuild-Depends: debhelper (&gt;= 9), python2.7 \r\n\r\nPackage: myprogram \r\nArchitecture: all \r\nDepends: python-gi \r\nDescription: My Program \r\nHere you can add a short description about your program.\r\n<\/pre>\n<p><b>compat<\/b>: This is just an important file for the dpkg system, it just includes the magical 9 number, leave it like that.<\/p>\n<pre>9\r\n<\/pre>\n<p><b>changelog<\/b>: Here you\u2019ll be able to add the changes you do on your program, for more information, please visit\u00a0<a href=\"https:\/\/www.debian.org\/doc\/debian-policy\/ch-source.html\" target=\"_blank\" rel=\"nofollow noopener\">Debian Package Changelog Source<\/a>.<\/p>\n<pre>myprogram (1.0) trusty; urgency=medium \r\n\r\n  * Add the new features here. \r\n  * Continue adding new changes here. \r\n  * And here. \r\n\r\n -- My Name Here &lt;myemail@mail.com&gt;  Sat, 27 Dec 2014 21:36:33 +0200\r\n<\/pre>\n<p><b>rules<\/b>: This file is responsible about running the installation process on the local machine to install the package, you can view more information<br \/>\nabout this file from here:\u00a0<a href=\"https:\/\/www.debian.org\/doc\/manuals\/maint-guide\/dreq.en.html#defaultrules\" target=\"_blank\" rel=\"nofollow noopener\">Debian Package Default Rules<\/a>.<\/p>\n<p>Though you won\u2019t need anything more for your Python program.<\/p>\n<pre>#!\/usr\/bin\/make -f \r\n# 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. \r\n%: \r\n    dh $@ \r\noverride_dh_auto_install: \r\n    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. \r\noverride_dh_auto_build:\r\n\r\n<\/pre>\n<p>Now thats we created all the necessary files for our program successfully, now let\u2019s start packaging it. First, make sure that you have installed some dependences for the build process before you start.<\/p>\n<pre>$ sudo apt-get update\r\n$ sudo apt-get install devscripts\r\n<\/pre>\n<p>Now imagine that the \u201c<b>myprogram<\/b>\u201d folder is in your home folder (<b>\/home\/user\/myprogram<\/b>) in order to package it as a Debian package, run the following commands.<\/p>\n<pre>$ cd \/home\/user\/myprogram\r\n$ debuild -us -uc\r\n<\/pre>\n<h5>Sample Output<\/h5>\n<pre>hanny@hanny-HP-Pavilion-15-Notebook-PC:~\/Projects\/myprogram$\r\ndebuild -us -uc dpkg-buildpackage -rfakeroot -D -us -uc\r\ndpkg-buildpackage: source package myprogram\r\ndpkg-buildpackage: source version 1.0\r\ndpkg-buildpackage: source distribution trusty\r\ndpkg-buildpackage: source changed by My Name Here\r\n&lt;myemail@email.com&gt;\r\ndpkg-source --before-build myprogram\r\ndpkg-buildpackage: host architecture i386\r\nfakeroot debian\/rules clean\r\ndh clean\r\ndh_testdir\r\ndh_auto_clean\r\n....\r\n.....\r\nFinished running lintian.\r\n<\/pre>\n<p>And that\u2019s it ! Your Debian package was created successfully:<\/p>\n<div id=\"attachment_10422\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Debian-Package.jpeg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10422\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Debian-Package-620x421.jpeg\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Debian-Package-620x421.jpeg 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Debian-Package.jpeg 863w\" alt=\"Created Debian Package\" width=\"620\" height=\"421\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Created Debian Package<\/p>\n<\/div>\n<p>In order to install it on any Debian-based distribution, run.<\/p>\n<pre>$ sudo dpkg -i myprogram_1.0_all.deb\r\n<\/pre>\n<p>Don\u2019t forget to replace the above file with the name of the package.. Now after you install the package, you can run the program from the applications menu.<\/p>\n<div id=\"attachment_10423\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Run-Program.jpeg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10423\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Run-Program-620x269.jpeg\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Run-Program-620x269.jpeg 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/Run-Program.jpeg 743w\" alt=\"Run Program\" width=\"620\" height=\"269\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Run Program<\/p>\n<\/div>\n<p>And it will work..<\/p>\n<div id=\"attachment_10424\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/First-Packaged-Program.jpeg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10424\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/First-Packaged-Program-620x373.jpeg\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/First-Packaged-Program-620x373.jpeg 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2014\/12\/First-Packaged-Program.jpeg 639w\" alt=\"First Packaged Program\" width=\"620\" height=\"373\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">First Packaged Program<\/p>\n<\/div>\n<p>Here ends the\u00a0<b>4th<\/b>\u00a0part of our series about PyGObject.. In the next lesson we\u2019ll explain how to localize the PyGObject application easily, till then stay tunned for it\u2026<\/p>\n<h1 class=\"post-title\">Translating PyGObject Applications into Different Languages \u2013 Part 5<\/h1>\n<p>We continue the PyGObject programming series with you and here in this\u00a0<b>5th<\/b>\u00a0part, we\u2019ll learn how to translate our PyGObject applications into different languages. Translating your applications is important if you\u2019re going to publish it for the world, it\u2019ll be more user friendly for end-users because not everybody understands English.<\/p>\n<div id=\"attachment_10900\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Translating-PyGObject-Applications-Languages.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10900\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Translating-PyGObject-Applications-Languages-620x297.jpg\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Translating-PyGObject-Applications-Languages-620x297.jpg 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Translating-PyGObject-Applications-Languages.jpg 720w\" alt=\"Translating PyGObject Application Language\" width=\"620\" height=\"297\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Translating PyGObject Application Language<\/p>\n<\/div>\n<h3>How the Translation Process Works<\/h3>\n<p>We can summarize the steps of translating any program under the Linux desktop using these steps:<\/p>\n<ol>\n<li>Extract the translatable strings from the Python file.<\/li>\n<li>Save the strings into a\u00a0<b>.pot<\/b>\u00a0file which is format that allows you to translate it later to other languages.<\/li>\n<li>Start translating the strings.<\/li>\n<li>Export the new translated strings into a\u00a0<b>.po<\/b>\u00a0file which will be automatically used when system language is changed.<\/li>\n<li>Add some small programmatic changes to the main Python file and the\u00a0<b>.desktop<\/b>\u00a0file.<\/li>\n<\/ol>\n<p>And that\u2019s it! After doing these steps your application will be ready for use for end-users from all around the globe (will.. You have to translate your program to all languages around the globe, though !), Sounds easy doesn\u2019t it? \ud83d\ude42<\/p>\n<p>First, to save some time, download the project files from below link and extract the file in your home directory.<\/p>\n<ol>\n<li><a href=\"https:\/\/copy.com\/TjyZAaNgeQ6BB7yn\" target=\"_blank\" rel=\"nofollow noopener\">https:\/\/copy.com\/TjyZAaNgeQ6BB7yn<\/a><\/li>\n<\/ol>\n<p>Open the \u201c<b>setup.py<\/b>\u201d file and notice the changes that we did:<\/p>\n<div id=\"attachment_10897\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Translation-Code.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10897\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Translation-Code-568x450.jpg\" sizes=\"auto, (max-width: 568px) 100vw, 568px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Translation-Code-568x450.jpg 568w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Translation-Code.jpg 775w\" alt=\"Translation Code\" width=\"568\" height=\"450\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Translation Code<\/p>\n<\/div>\n<pre># 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\r\nfrom distutils.core import setup\r\n\r\n# Those modules will help us in creating the translation files for the program automatically.\r\nfrom subprocess import call\r\nfrom glob import glob\r\nfrom os.path import splitext, split\r\n\r\n# DON'T FOTGET TO REPLACE 'myprogram' WITH THE NAME OF YOUR PROGRAM IN EVERY FILE IN THIS PROJECT.\r\n\r\ndata_files = [ (\"lib\/myprogram\", [\"ui.glade\"]), # This is going to install the \"ui.glade\" file under the \/usr\/lib\/myprogram path.\r\n                     (\"share\/applications\", [\"<b>myprogram.desktop<\/b>\"]) ] \r\n\r\n# This code does everything needed for creating the translation files, first it will look for all the .po files inside the po folder, then it will define the default path for where to install the translation files (.mo) on the local system, then it's going to create the directory on the local system for the translation files of our program and finally it's going to convert all the .po files into .mo files using the \"msgfmt\" command.\r\npo_files = glob(\"po\/*.po\")\r\nfor po_file in po_files:\r\n  lang = splitext(split(po_file)[1])[0]\r\n  mo_path = \"locale\/{}\/LC_MESSAGES\/myprogram.mo\".format(lang)\r\n# Make locale directories\r\n  call(\"mkdir -p locale\/{}\/LC_MESSAGES\/\".format(lang), shell=True)\r\n# Generate mo files\r\n  call(\"msgfmt {} -o {}\".format(po_file, mo_path), shell=True)\r\n  locales = map(lambda i: ('share\/'+i, [i+'\/myprogram.mo', ]), glob('locale\/*\/LC_MESSAGES'))\r\n\r\n# Here, the installer will automatically add the .mo files to the data files to install them later.\r\n  data_files.extend(locales)\r\n\r\nsetup(name = \"<b>myprogram<\/b>\", # Name of the program.\r\n      version = \"<b>1.0<\/b>\", # Version of the program.\r\n      description = \"<b>An easy-to-use web interface to create &amp; share pastes easily<\/b>\", # You don't need any help here.\r\n      author = \"<b>TecMint<\/b>\", # Nor here.\r\n      author_email = \"<b>myemail@mail.com<\/b>\",# Nor here :D\r\n      url = \"<b>http:\/\/example.com<\/b>\", # If you have a website for you program.. put it here.\r\n      license='<b>GPLv3<\/b>', # The license of the program.\r\n      scripts=['<b>myprogram<\/b>'], # 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.\r\n\r\n# 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\r\n      data_files=data_files) # 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.\r\n<\/pre>\n<p>Also open the \u201c<b>myprogram<\/b>\u201d file and see the programmatic changes that we did, all the changes are explained in the comments:<\/p>\n<pre>#!\/usr\/bin\/python \r\n# -*- coding: utf-8 -*- \r\n\r\n## Replace your name and email.\r\n# My Name &lt;myemail@email.com&gt;\r\n\r\n## Here you must add the license of the file, replace \"MyProgram\" with your program name.\r\n# License:\r\n#    MyProgram is free software: you can redistribute it and\/or modify\r\n#    it under the terms of the GNU General Public License as published by\r\n#    the Free Software Foundation, either version 3 of the License, or\r\n#    (at your option) any later version.\r\n#\r\n#    MyProgram is distributed in the hope that it will be useful,\r\n#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n#    GNU General Public License for more details.\r\n#\r\n#    You should have received a copy of the GNU General Public License\r\n#    along with MyProgram.  If not, see &lt;http:\/\/www.gnu.org\/licenses\/&gt;.\r\n\r\nfrom gi.repository import Gtk \r\nimport os, gettext, locale\r\n\r\n## This is the programmatic change that you need to add to the Python file, just replace \"myprogram\" with the name of your program. The \"locale\" and \"gettext\" modules will take care about the rest of the operation.\r\nlocale.setlocale(locale.LC_ALL, '')\r\ngettext.bindtextdomain('myprogram', '\/usr\/share\/locale')\r\ngettext.textdomain('myprogram')\r\n_ = gettext.gettext\r\ngettext.install(\"myprogram\", \"\/usr\/share\/locale\")\r\n\r\nclass Handler: \r\n  \r\n  def openterminal(self, button): \r\n    ## When the user clicks on the first button, the terminal will be opened.\r\n    os.system(\"x-terminal-emulator \")\r\n  \r\n  def closeprogram(self, button):\r\n    Gtk.main_quit()\r\n    \r\n# Nothing new here.. We just imported the 'ui.glade' file. \r\nbuilder = Gtk.Builder() \r\nbuilder.add_from_file(\"\/usr\/lib\/myprogram\/ui.glade\") \r\nbuilder.connect_signals(Handler()) \r\n\r\nlabel = builder.get_object(\"label1\")\r\n# Here's another small change, instead of setting the text to (\"Welcome to my Test program!\") we must add a \"_\" char before it in order to allow the responsible scripts about the translation process to recognize that it's a translatable string.\r\nlabel.set_text(_(\"Welcome to my Test program !\"))\r\n\r\nbutton = builder.get_object(\"button2\")\r\n# And here's the same thing.. You must do this for all the texts in your program, elsewhere, they won't be translated.\r\nbutton.set_label(_(\"Click on me to open the Terminal\"))\r\n\r\n\r\nwindow = builder.get_object(\"window1\") \r\nwindow.connect(\"delete-event\", Gtk.main_quit)\r\nwindow.show_all() \r\nGtk.main()<\/pre>\n<p>Now.. Let\u2019s start translating our program. First create the\u00a0<b>.pot<\/b>\u00a0file (a file that contains all the translatable strings in the program) so that you<br \/>\ncan start translating using the following command:<\/p>\n<pre>$ cd myprogram\r\n$ xgettext --language=Python --keyword=_ -o po\/myprogram.pot myprogram\r\n<\/pre>\n<p>This is going to create the \u201c<b>myprogram.pot<\/b>\u201d file inside the \u201c<b>po<\/b>\u201d folder in the main project folder which contains the following code:<\/p>\n<pre># SOME DESCRIPTIVE TITLE.\r\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\r\n# This file is distributed under the same license as the PACKAGE package.\r\n# FIRST AUTHOR &lt;EMAIL@ADDRESS&gt;, YEAR.\r\n#\r\n#, fuzzy\r\nmsgid \"\"\r\nmsgstr \"\"\r\n\"Project-Id-Version: PACKAGE VERSION\\n\"\r\n\"Report-Msgid-Bugs-To: \\n\"\r\n\"POT-Creation-Date: 2014-12-29 21:28+0200\\n\"\r\n\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\r\n\"Last-Translator: FULL NAME &lt;EMAIL@ADDRESS&gt;\\n\"\r\n\"Language-Team: LANGUAGE &lt;LL@li.org&gt;\\n\"\r\n\"Language: \\n\"\r\n\"MIME-Version: 1.0\\n\"\r\n\"Content-Type: text\/plain; charset=CHARSET\\n\"\r\n\"Content-Transfer-Encoding: 8bit\\n\"\r\n\r\n#: myprogram:48\r\nmsgid \"Welcome to my Test program !\"\r\nmsgstr \"\"\r\n\r\n#: myprogram:52\r\nmsgid \"Click on me to open the Terminal\"\r\nmsgstr \"\"\r\n<\/pre>\n<p>Now in order to start translating the strings.. Create a separated file for each language that you want to translate your program to using the \u201c<b>ISO-639-1<\/b>\u201d languages codes inside the \u201c<b>po<\/b>\u201d folder, for example, if you want to translate your program to\u00a0<b>Arabic<\/b>, create a file called \u201c<b>ar.po<\/b>\u201d and copy the contents from the \u201c<b>myprogram.pot<\/b>\u201d file to it.<\/p>\n<p>If you want to translate your program to\u00a0<b>German<\/b>, create a \u201c<b>de.po<\/b>\u201d file and copy the contents from the \u201c<b>myprogram.pot<\/b>\u201d file to it.. and so one, you must create a file for each language that you want to translate your program to.<\/p>\n<p>Now, we\u2019ll work on the \u201c<b>ar.po<\/b>\u201d file, copy the contents from the \u201c<b>myprogram.pot<\/b>\u201d file and put it inside that file and edit the following:<\/p>\n<ol>\n<li><b>SOME DESCRIPTIVE TITLE<\/b>: you can enter the title of your project here if you want.<\/li>\n<li><b>YEAR THE PACKAGE\u2019S COPYRIGHT HOLDER<\/b>: replace it with the year that you\u2019ve created the project.<\/li>\n<li><b>PACKAGE<\/b>: replace it with the name of the package.<\/li>\n<li><b>FIRST AUTHOR &lt;EMAIL@ADDRESS&gt;, YEAR<\/b>: replace this with your real name, Email and the year that you translated the file.<\/li>\n<li><b>PACKAGE VERSION<\/b>: replace it with the package version from the debian\/control file.<\/li>\n<li><b>YEAR-MO-DA HO:MI+ZONE<\/b>: doesn\u2019t need explanation, you can change it to any date you want.<\/li>\n<li><b>FULL NAME &lt;EMAIL@ADDRESS&gt;<\/b>: also replace it your your name and Email.<\/li>\n<li><b>Language-Team<\/b>: replace it with the name of the language that you\u2019re translating to, for example \u201cArabic\u201d or \u201cFrench\u201d.<\/li>\n<li><b>Language<\/b>: here, you must insert the ISO-639-1 code for the language that you\u2019re translating to, for example \u201car\u201d, \u201cfr\u201d, \u201cde\u201d..etc, you can find a complete list\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_ISO_639-1_codes\" target=\"blank\" rel=\"nofollw\">here<\/a>.<\/li>\n<li><b>CHARSET<\/b>: this step is important, replace this string with \u201cUTF-8\u201d (without the quotes) which supports most languages.<\/li>\n<\/ol>\n<p>Now start translating! Add your translation for each string after the quotes in \u201c<b>msgstr<\/b>\u201d. Save the file and exit. A good translation file for the<br \/>\nArabic language as an example should look like this:<\/p>\n<pre># My Program\r\n# Copyright (C) 2014\r\n# This file is distributed under the same license as the myprogram package.\r\n# Hanny Helal &lt;youremail@mail.com&lt;, 2014.\r\n#\r\n#, fuzzy\r\nmsgid \"\"\r\nmsgstr \"\"\r\n\"Project-Id-Version: <b>1.0\\n<\/b>\"\r\n\"Report-Msgid-Bugs-To: \\n\"\r\n\"POT-Creation-Date: <b>2014-12-29 21:28+0200<\/b>\\n\"\r\n\"PO-Revision-Date: <b>2014-12-29 22:28+0200<\/b>\\n\"\r\n\"Last-Translator: <b>M.Hanny Sabbagh &lt;hannysabbagh&lt;@hotmail.com&lt;<\/b>\\n\"\r\n\"Language-Team: <b>Arabic &lt;LL@li.org&lt;<\/b>\\n\"\r\n\"Language: <b>ar\\<\/b>n\"\r\n\"MIME-Version: <b>1.0<\/b>\\n\"\r\n\"Content-Type: text\/plain; <b>charset=UTF-8<\/b>\\n\"\r\n\"Content-Transfer-Encoding: <b>8bit<\/b>\\n\"\r\n\r\n#: myprogram:48\r\nmsgid \"<b>Welcome to my Test program !<\/b>\"\r\nmsgstr \"<b>\u0623\u0647\u0644\u064b\u0627 \u0628\u0643 \u0625\u0644\u0649 \u0628\u0631\u0646\u0627\u0645\u062c\u064a \u0627\u0644\u0627\u062e\u062a\u0628\u0627\u0631\u064a!<\/b>\"\r\n\r\n#: myprogram:52\r\nmsgid \"<b>Click on me to open the Terminal<\/b>\"\r\nmsgstr \"<b>\u0627\u0636\u063a\u0637 \u0639\u0644\u064a\u0651 \u0644\u0641\u062a\u062d \u0627\u0644\u0637\u0631\u0641\u064a\u0629<\/b>\"\r\n<\/pre>\n<p>There\u2019s nothing more to do, just package the program using the following command:<\/p>\n<pre>$ debuild -us -uc\r\n<\/pre>\n<p>Now try to install the new created package using the following command.<\/p>\n<pre>$ sudo dpkg -i myprogram_1.0_all.deb\r\n<\/pre>\n<p>And change the system language using the \u201c<b>Language Support<\/b>\u201d program or using any other program to\u00a0<b>Arabic<\/b>(or the language the you\u2019ve translated your file to):<\/p>\n<div id=\"attachment_10898\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Language-Support.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10898\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Language-Support-620x437.jpg\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" srcset=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Language-Support-620x437.jpg 620w, https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Language-Support.jpg 789w\" alt=\"Language Support\" width=\"620\" height=\"437\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Language Support<\/p>\n<\/div>\n<p>After selecting, your program will be translated to Arabic language.<\/p>\n<div id=\"attachment_10899\" class=\"wp-caption aligncenter\">\n<p><a href=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Translated-to-Arabic.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-10899\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2015\/01\/Translated-to-Arabic.jpg\" alt=\"Translated to Arabic\" width=\"385\" height=\"344\" data-lazy-loaded=\"true\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Translated to Arabic<\/p>\n<\/div>\n<p>Here ends our series about PyGObject programming for the Linux desktop, of course there are many other things that you can learn from the\u00a0<a href=\"https:\/\/python-gtk-3-tutorial.readthedocs.org\/en\/latest\/\" target=\"_blank\" rel=\"nofollow noopener\">official documentation<\/a>\u00a0and the\u00a0<a href=\"https:\/\/lazka.github.io\/pgi-docs\/\" target=\"_blank\" rel=\"nofollow noopener\">Python GI API<\/a>\u00a0reference..<\/p>\n<p>What do you think about the series? Do you find it useful? Were you able to create your first application by following this series? Share us your thoughts!<\/p>\n<p><a style=\"font-size: 1rem;\" href=\"https:\/\/www.tecmint.com\/create-gui-applications-in-linux\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Creating applications on Linux can be done using different ways, but there are a limited ways of doing, so using the simplest and the most functional programming languages and libraries, that\u2019s why we\u2019re going to have a quick look about creating applications under the Linux desktop using the GTK+ library with Python programming language which &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.appservgrid.com\/paw92\/index.php\/2019\/03\/21\/how-to-create-gui-applications-under-linux-desktop-using-pygobject\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;How to Create GUI Applications Under Linux Desktop Using PyGObject&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-12017","post","type-post","status-publish","format-standard","hentry","category-linux"],"_links":{"self":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/12017","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/comments?post=12017"}],"version-history":[{"count":1,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/12017\/revisions"}],"predecessor-version":[{"id":12018,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/12017\/revisions\/12018"}],"wp:attachment":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/media?parent=12017"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/categories?post=12017"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/tags?post=12017"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}