Creeu el vostre propi navegador web i aplicacions de gravació d'escriptori amb PyGobject - Part 3


Aquesta és la tercera part de la sèrie sobre la creació d'aplicacions GUI a l'escriptori Linux mitjançant PyGObject. Avui parlarem de l'ús d'alguns mòduls i biblioteques de Python avançats als nostres programes com 'os', 'WebKit', 'sol·licituds' i altres, al costat d'alguna altra informació útil per a la programació.

Heu de revisar totes aquestes parts anteriors de la sèrie a partir d'aquí, per continuar amb més instruccions sobre com crear aplicacions més avançades:

  1. Creeu aplicacions GUI a l'escriptori Linux amb PyGObject - Part 1
  2. Creació d'aplicacions PyGobject avançades a Linux - Part 2

Els mòduls i les biblioteques de Python són molt útils, en lloc d'escriure molts subprogrames per fer treballs complicats que requereixen molt de temps i treball, només podeu importar-los! Sí, només importeu els mòduls i biblioteques que necessiteu al vostre programa i podreu estalviar molt de temps i esforços per completar el vostre programa.

Hi ha molts mòduls famosos per a Python, que podeu trobar a Python Module Index.

També podeu importar biblioteques per al vostre programa Python, des de “gi.repository import Gtk” aquesta línia importa la biblioteca GTK al programa Python, hi ha moltes altres biblioteques com Gdk, WebKit... etc.

Creació d'aplicacions GUI avançades

Avui, crearem 2 programes:

  1. Un navegador web senzill; que utilitzarà la biblioteca WebKit.
  2. Una gravadora d'escriptori amb l'ordre avconv; que utilitzarà el mòdul ‘os’ de Python.

No explicaré com arrossegar i deixar anar ginys al dissenyador de Glade a partir d'ara, només us diré el nom dels ginys que heu de crear, a més us donaré el .glade per a cada programa, i el fitxer Python segur.

Per crear un navegador web, haurem d'utilitzar el motor \WebKit”, que és un motor de renderització de codi obert per a la web, és el mateix que s'utilitza a Chrome/Chromium, per obtenir més informació al respecte, podeu consultar el lloc web oficial de Webkit.org.

Primer, haurem de crear la GUI, obrir el dissenyador de Glade i afegir els ginys següents. Per obtenir més informació sobre com crear ginys, seguiu la Part 1 i la Part 2 d'aquesta sèrie (enllaços indicats més amunt).

  1. Creeu el giny window1.
  2. Creeu el giny box1 i box2.
  3. Creeu el giny button1 i button2.
  4. Creeu el giny entrada1.
  5. Creeu el giny scrollwindow1.

Després de crear ginys, obtindreu la següent interfície.

No hi ha res de nou, excepte el giny \Finestra desplaçada; aquest giny és important per permetre que el motor WebKit s'implanti dins d'ell, utilitzant el \Fiestra desplaçada”, també podreu desplaçar-vos horitzontalment i verticalment mentre navegueu pels llocs web.

Ara haureu d'afegir el controlador \backbutton_clicked al senyal del botó Enrere \clic, \refreshbutton_clicked b> controlador al botó d'actualització \senyal de clic i gestor de \enterkey_clicked al senyal \activat per a l'entrada .

El fitxer .glade complet per a la interfície és aquí.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
  <requires lib="gtk+" version="3.10"/>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <property name="title" translatable="yes">Our Simple Browser</property>
    <property name="window_position">center</property>
    <property name="default_width">1000</property>
    <property name="default_height">600</property>
    <property name="icon_name">applications-internet</property>
    <child>
      <object class="GtkBox" id="box1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkBox" id="box2">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkButton" id="button1">
                <property name="label">gtk-go-back</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="relief">half</property>
                <property name="use_stock">True</property>
                <property name="always_show_image">True</property>
                <signal name="clicked" handler="backbutton_clicked" swapped="no"/>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="button2">
                <property name="label">gtk-refresh</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="relief">half</property>
                <property name="use_stock">True</property>
                <property name="always_show_image">True</property>
                <signal name="clicked" handler="refreshbutton_clicked" swapped="no"/>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <object class="GtkEntry" id="entry1">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <signal name="activate" handler="enterkey_clicked" swapped="no"/>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">2</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkScrolledWindow" id="scrolledwindow1">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="hscrollbar_policy">always</property>
            <property name="shadow_type">in</property>
            <child>
              <placeholder/>
            </child>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

Ara copieu el codi anterior i enganxeu-lo al fitxer \ui.glade de la vostra carpeta d'inici. Ara creeu un fitxer nou anomenat \mywebbrowser.py i introduïu el següent codi dins, tota l'explicació està als comentaris.

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

## Here we imported both Gtk library and the WebKit engine. 
from gi.repository import Gtk, WebKit 

class Handler: 
  
  def backbutton_clicked(self, button): 
  ## 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. 
    browserholder.go_back() 

  def refreshbutton_clicked(self, button): 
  ## Same thing here, the '.reload()' method is activated when the 'Refresh' button is clicked. 
    browserholder.reload() 
    
  def enterkey_clicked(self, button): 
  ## 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. 
    browserholder.load_uri(urlentry.get_text()) 
    
## Nothing new here.. We just imported the 'ui.glade' file. 
builder = Gtk.Builder() 
builder.add_from_file("ui.glade") 
builder.connect_signals(Handler()) 

window = builder.get_object("window1") 

## 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. 
browserholder = WebKit.WebView() 

## To disallow editing the webpage. 
browserholder.set_editable(False) 

## The default URL to be loaded, we used the 'load_uri()' method. 
browserholder.load_uri("https://linux-console.net") 

urlentry = builder.get_object("entry1") 
urlentry.set_text("https://linux-console.net") 

## Here we imported the scrolledwindow1 object from the ui.glade file. 
scrolled_window = builder.get_object("scrolledwindow1") 

## We used the '.add()' method to add the 'browserholder' object to the scrolled window, which contains our WebKit browser. 
scrolled_window.add(browserholder) 

## And finally, we showed the 'browserholder' object using the '.show()' method. 
browserholder.show() 
 
## Give that developer a cookie ! 
window.connect("delete-event", Gtk.main_quit) 
window.show_all() 
Gtk.main()

Deseu el fitxer i executeu-lo.

$ chmod 755 mywebbrowser.py
$ ./mywebbrowser.py

I això és el que obtindreu.

Podeu consultar la documentació oficial de WebKitGtk per descobrir més opcions.

En aquesta secció, aprendrem a executar ordres del sistema local o scripts d'intèrpret d'ordres des del fitxer Python mitjançant el mòdul 'os', que ens ajudarà a crear un gravador de pantalla senzill per a l'escriptori mitjançant el Ordre 'avconv'.

Obriu el dissenyador de Glade i creeu els ginys següents:

  1. Creeu el giny window1.
  2. Creeu el widget box1.
  3. Creeu ginys button1, button2 i button3.
  4. Creeu el giny entrada1.

Després de crear els ginys anteriors, obtindreu la interfície següent.

Aquí teniu el fitxer ui.glade complet.

<?xml version="1.0" encoding="UTF-8"?> 
<!-- Generated with glade 3.16.1 --> 
<interface> 
  <requires lib="gtk+" version="3.10"/> 
  <object class="GtkWindow" id="window1"> 
    <property name="can_focus">False</property> 
    <property name="title" translatable="yes">Our Simple Recorder</property> 
    <property name="window_position">center</property> 
    <property name="default_width">300</property> 
    <property name="default_height">30</property> 
    <property name="icon_name">applications-multimedia</property> 
    <child> 
      <object class="GtkBox" id="box1"> 
        <property name="visible">True</property> 
        <property name="can_focus">False</property> 
        <child> 
          <object class="GtkEntry" id="entry1"> 
            <property name="visible">True</property> 
            <property name="can_focus">True</property> 
          </object> 
          <packing> 
            <property name="expand">False</property> 
            <property name="fill">True</property> 
            <property name="position">0</property> 
          </packing> 
        </child> 
        <child> 
          <object class="GtkButton" id="button1"> 
            <property name="label">gtk-media-record</property> 
            <property name="visible">True</property> 
            <property name="can_focus">True</property> 
            <property name="receives_default">True</property> 
            <property name="use_stock">True</property> 
            <property name="always_show_image">True</property> 
            <signal name="clicked" handler="recordbutton" swapped="no"/> 
          </object> 
          <packing> 
            <property name="expand">True</property> 
            <property name="fill">True</property> 
            <property name="position">1</property> 
          </packing> 
        </child> 
        <child> 
          <object class="GtkButton" id="button2"> 
            <property name="label">gtk-media-stop</property> 
            <property name="visible">True</property> 
            <property name="can_focus">True</property> 
            <property name="receives_default">True</property> 
            <property name="use_stock">True</property> 
            <property name="always_show_image">True</property> 
            <signal name="clicked" handler="stopbutton" swapped="no"/> 
          </object> 
          <packing> 
            <property name="expand">True</property> 
            <property name="fill">True</property> 
            <property name="position">2</property> 
          </packing> 
        </child> 
        <child> 
          <object class="GtkButton" id="button3"> 
            <property name="label">gtk-media-play</property> 
            <property name="visible">True</property> 
            <property name="can_focus">True</property> 
            <property name="receives_default">True</property> 
            <property name="use_stock">True</property> 
            <property name="always_show_image">True</property> 
            <signal name="clicked" handler="playbutton" swapped="no"/> 
          </object> 
          <packing> 
            <property name="expand">True</property> 
            <property name="fill">True</property> 
            <property name="position">3</property> 
          </packing> 
        </child> 
      </object> 
    </child> 
  </object> 
</interface>

Com és habitual, copieu el codi anterior i enganxeu-lo al fitxer \ui.glade del vostre directori d'inici, creeu un nou fitxer \myrecorder.py i introduïu-lo. el següent codi al seu interior (cada nova línia s'explica als comentaris).

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

## Here we imported both Gtk library and the os module. 
from gi.repository import Gtk 
import os 
        
class Handler: 
  def recordbutton(self, button): 
    ## We defined a variable: 'filepathandname', we assigned the bash local variable '$HOME' to it + "/" + the file name from the text entry box. 
    filepathandname = os.environ["HOME"] + "/" + entry.get_text() 
    
    ## Here exported the 'filepathandname' variable from Python to the 'filename' variable in the shell. 
    os.environ["filename"] = filepathandname 
    
    ## Using 'os.system(COMMAND)' we can execute any shell command or shell script, here we executed the 'avconv' command to record the desktop video & audio. 
    os.system("avconv -f x11grab -r 25 -s `xdpyinfo | grep 'dimensions:'|awk '{print $2}'` -i :0.0 -vcodec libx264 -threads 4 $filename -y & ") 
    
    
  def stopbutton(self, button): 
    ## Run the 'killall avconv' command when the stop button is clicked. 
    os.system("killall avconv") 
    
  def playbutton(self, button): 
  ## Run the 'avplay' command in the shell to play the recorded file when the play button is clicked. 
    os.system("avplay $filename &") 
    
    
## Nothing new here.. We just imported the 'ui.glade' file. 
builder = Gtk.Builder() 
builder.add_from_file("ui.glade") 
builder.connect_signals(Handler()) 

window = builder.get_object("window1") 
entry = builder.get_object("entry1") 
entry.set_text("myrecording-file.avi") 

## Give that developer a cookie ! 
window.connect("delete-event", Gtk.main_quit) 
window.show_all() 
Gtk.main()

Ara executeu el fitxer aplicant les ordres següents al terminal.

$ chmod 755 myrecorder.py
$ ./myrecorder.py

I tens la teva primera gravadora d'escriptori.

Podeu trobar més informació sobre el mòdul 'os' a la biblioteca del sistema operatiu Python.

I això és tot, crear aplicacions per a l'escriptori Linux no és difícil amb PyGObject, només cal crear la GUI, importar alguns mòduls i enllaçar el fitxer Python amb la GUI, ni més ni menys. Hi ha molts tutorials útils sobre com fer-ho al lloc web de PyGObject:

Heu provat de crear aplicacions amb PyGObject? Què et sembla fer-ho? Quines aplicacions has desenvolupat abans?