viernes, 26 de julio de 2013

Muy rápido, muy fácil, navegador web con Python

Python es un lenguaje que por su simpleza y versatilidad ha llegado a ser usado en muchos y muy buenos proyectos. A continuación veremos en este post el código de un navegador web muy simple, con soporte para la mayoría de las características de HTML5. Para poder hacer esto usamos Python2.7 y PySide de 32 bits si el sistema operativo es Windows, si es Linux podemos instalarlo usando los repositorios inestables o de pruebas mediante el clásico apt-get así:

apt-get install python-pyside

Aquí vamos:
# -*- coding: utf-8 -*-
# Tested in Python2.7

from PySide import QtCore, QtGui
from PySide import QtWebKit
from PySide import QtNetwork


class Navegador(QtGui.QWidget):

    def __init__(self):
        # constructor de la clase
        super(Navegador, self).__init__(parent=None)
        self.setWindowTitle("Python Navigator")
        self.showMaximized()
        self.gridLayout = QtGui.QGridLayout(self)
        self.btnAtras = QtGui.QPushButton(self, text='atras')
        self.gridLayout.addWidget(self.btnAtras, 0, 0, 1, 1)
        self.btnAdelante = QtGui.QPushButton(self, text='adelante')
        self.gridLayout.addWidget(self.btnAdelante, 0, 1, 1, 1)
        self.label = QtGui.QLabel(u"Dirección", self)
        self.gridLayout.addWidget(self.label, 0, 2, 1, 1)
        self.txtUrl = QtGui.QLineEdit(self)
        self.gridLayout.addWidget(self.txtUrl, 0, 3, 1, 1)
        self.wvNavegador = QtWebKit.QWebView(self)
        self.gridLayout.addWidget(self.wvNavegador, 1, 0, 1, 4)

        QtNetwork.QNetworkProxyFactory.setUseSystemConfiguration(True)
        QtWebKit.QWebSettings.globalSettings().setAttribute(
            QtWebKit.QWebSettings.PluginsEnabled, True)
        QtWebKit.QWebSettings.globalSettings().setAttribute(
            QtWebKit.QWebSettings.JavascriptCanOpenWindows, True)
        QtWebKit.QWebSettings.globalSettings().setAttribute(
            QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)

        QtCore.QObject.connect(
            self.txtUrl,
            QtCore.SIGNAL("returnPressed()"),
            self.cargarUrl)
        QtCore.QObject.connect(
            self.btnAtras,
            QtCore.SIGNAL("clicked()"),
            self.wvNavegador.back)
        QtCore.QObject.connect(
            self.btnAdelante,
            QtCore.SIGNAL("clicked()"),
            self.wvNavegador.forward)

        _url = "http://www.python.org"
        self.wvNavegador.load(QtCore.QUrl(_url))
        self.txtUrl.setText(_url)

    def cargarUrl(self):
        url = self.txtUrl.text()
        url = url if url.startswith(
            "http://") or url.startswith(
                "https://") else "http://{url}".format(
                    url=url)
        self.wvNavegador.load(QtCore.QUrl(url))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    nav = Navegador()
    nav.show()
    sys.exit(app.exec_())

Podemos ver que en el bloque de código anterior se crea la clase navegador, en la cual se crean los controles básicos (la caja de texto para la URL, botones de atrás y adelante, el espacio de navegación), después de esto se "empaquetan" por así decirlo en un gridlayout, el cual nos permite hacer que los controles se ajusten de manera dinámica cuando cambie el tamaño de la ventana. Después se habilitan los plugins del elemento mediante el cual se navega para que sea posible ver vídeos en youtube e inspeccionar elementos (muestra el DOM, los scripts y demás de manera muy similar a la de Google Chrome) mediante click derecho, luego se enlazan los botones al navegador mediante los eventos de click y la barra de direcciones al navegador mediante el evento returnPressed y después se carga la URL inicial ("http://www.python.org").
Finalmente se instancia los objetos necesarios para iniciar nuestro navegador.

Fácil, efectivo y contundente, un navegador muy simple con menos de 70 lineas de código.

Aquí esta el enlace al repositorio en GitHub (siéntanse libres de modificarlo) y abajo les dejo una imagen de como se ve.


3 comentarios: