Tabla de contenido
Una vez más aquí. Hoy vengo a dejar un pequeño artículo para alguien que me pidió hace unos días consejo para poder seguir trabajando con el navegador web mientras, al tiempo que quería poder seguir reproduciendo contenido. Esta persona por lo que parece tiene también la costumbre de tener un buen puñado de páginas web abiertas al mismo tiempo, por lo que cuando empiezas a reproducir contenido, según los recursos del equipo en cuestión, se puede resentir un poco el rendimiento.
Bueno, pues para evitar que esto suceda, me acordé de que con Python y PyQt5 se puede crear algo así como una web app, Aun que creo que realmente no lo es, ya que esto se va a ejecutar en nuestro ordenador local, en lugar de utilizar un servidor remoto accesible desde internet. Las cuales nos van a permitir interactuar con una página web (con ciertas limitaciones) sin sobrecargar más nuestro navegador web.

Si queremos ejecutar esta aplicación con Python, necesitaremos Python instalado (resulta evidente). Yo utilizo Python3. También es necesario tener instalado el paquete webengine de PyQt5 (PyQt6 también vale, pero el código ya no será el mismo). Además tuve que instalar Pygame. Todo esto se puede instalar en Ubuntu siguiendo los pasos que describo en el repositorio en el que alojé este proyecto.
El primer código que vamos a ver es un script es un menú de canales que utiliza la biblioteca PyQt5 de Python, y con el que vamos a crear una interfaz gráfica de usuario. El menú nos va a mostrar una lista de archivos Python, los cuales va a encontrar en un directorio llamado «canales», permitiendo al usuario seleccionar cualquiera de ellos para ejecutarlo.
Al ejecutar este menú también instala automáticamente la biblioteca Pygame al iniciar la aplicación, utilizando el módulo subprocess para ejecutar el comando pip install. Esto permite a los scripts de canal utilizar la biblioteca Pygame si es necesario.
En resumen, el script crea una interfaz gráfica de usuario que permite al usuario seleccionar un archivo Python para ejecutarlo. Tambiíen se asegura de que la biblioteca Pygame esté instalada antes de ejecutar los archivos Python del menú.
El archivo en el que vamos a guardar el código lo llamé menu.py, y dentro coloqué el siguiente código:
import os import sys import subprocess from PyQt5.QtWidgets import QApplication, QMainWindow, QListWidget, QListWidgetItem from PyQt5.QtCore import Qt from PyQt5.QtGui import QColor, QIcon, QFont class MainWindow(QMainWindow): def __init__(self): super().__init__() self.initUI() self.instalar_pygame() # Instalar Pygame al iniciar la aplicación def initUI(self): self.setWindowTitle('Menú de canales') self.setGeometry(100, 100, 400, 300) # Establecer el icono de la ventana principal self.setWindowIcon(QIcon('./icono.png')) # Crear un QListWidget para mostrar el contenido del directorio "canales" self.listWidget = QListWidget(self) self.setCentralWidget(self.listWidget) # Obtener los archivos Python en el directorio "canales" ordenados alfabéticamente canales_dir = './canales/' archivos = os.listdir(canales_dir) py_files = [archivo for archivo in archivos if archivo.endswith('.py')] py_files.sort() # Ordenar los archivos alfabéticamente # Crear un QListWidgetItem para cada archivo Python for py_file in py_files: item = QListWidgetItem(py_file) item.setToolTip(os.path.abspath(os.path.join(canales_dir, py_file))) self.listWidget.addItem(item) # Conectar la señal itemDoubleClicked al slot ejecutar_script self.listWidget.itemDoubleClicked.connect(self.ejecutar_script) # Aplicar estilo personalizado al listado de canales self.listWidget.setStyleSheet(""" QListWidget { background-color: #F0F0F0; border: 1px solid #CCC; border-radius: 5px; padding: 5px; font-size: 14px; } QListWidget::item { background-color: #FFF; border-radius: 5px; padding: 5px; } QListWidget::item:hover { background-color: #E6E6E6; color: #000; font-weight: bold; } QListWidget::item:selected { background-color: #BFBFBF; color: #000; font-weight: bold; } """) self.show() def instalar_pygame(self): # Instalar Pygame con Python 3 try: subprocess.check_call([sys.executable, '-m', 'pip', 'install', '-U', 'pygame']) except subprocess.CalledProcessError as e: print(f"Error al instalar pygame: {e}") def ejecutar_script(self, item): # Ejecutar el archivo Python seleccionado con Python 3 ruta_absoluta = item.toolTip() subprocess.Popen([sys.executable, ruta_absoluta]) if __name__ == '__main__': app = QApplication(sys.argv) mainWindow = MainWindow() sys.exit(app.exec_())
Con esto habremos creado el menú necesario para leer el contenido de la carpeta llamada «canales», y listar todos los archivo .py que encuentre dentro. Por eso, el siguiente paso lógico es mostrar el contenido de estos archivos que se encontrarán dentro de la carpeta «canales».
Canales o páginas web
Para cada página o servicio que queramos disponer, será necesario añadir un nuevo archivo. Pero solo habrá que modificar unos pocos parámetros de unos a otros. Parámetros como son el Título de la ventana, la URL que se va a cargar y el nombre del icono que se va a mostrar en la barra de herramientas.
El código que vamos a ver es un ejemplo de una aplicación de escritorio usando la biblioteca PyQt5 de Python, en el que se va a cargar la página web de MiTele. Con esta aplicación conseguiremos una vista web que muestra el sitio web de MiTele, si necesidad de tener abierto el navegador web.
Comenzará el código importando los módulos necesarios, como el módulo os para manejar archivos y rutas del sistema operativo. También se importará el módulo sys para acceder a variables y funciones específicas del intérprete de Python. Además de los módulos necesarios de PyQt5.
La clase Ui_MainWindow define la interfaz de usuario de la ventana principal. En el método setupUi se configura la geometría de la ventana, se establece un título, se crea un widget central para la ventana y se agrega un widget de vista web a un layout vertical. Además, se establece la URL del sitio web a cargar y se establece el icono de la ventana principal.
Luego, se crea una instancia de la clase QApplication de PyQt5 y establece un identificador de la aplicación si el sistema operativo es Windows. A continuación, se crea una instancia de la ventana principal y se configura la interfaz de usuario llamando al método setupUi de la clase Ui_MainWindow.
Esto, como decía líneas más arriba, se va a guardar dentro de un archivo .py en la carpeta «canales». El código para ver la web de MiTele, será el siguiente:
import os # Importa el módulo "os" para manejar archivos y rutas del sistema operativo import sys # Importa el módulo "sys" para acceder a variables y funciones específicas del intérprete de Python from PyQt5 import QtCore, QtGui, QtWidgets # Importa los módulos necesarios de PyQt5 from PyQt5 import QtWebEngineWidgets # Importa el módulo "QtWebEngineWidgets" de PyQt5 class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.setGeometry(100, 100, 1200, 760) # Establece la geometría de la ventana principal MainWindow.setMinimumSize(400, 500) # Establece el tamaño mínimo de la ventana principal MainWindow.setWindowTitle("Servicio MiTele") # Establece el título de la ventana principal self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) # Crea un layout vertical para el widget central self.webEngineView = QtWebEngineWidgets.QWebEngineView(self.centralwidget) # Crea un widget de vista web self.verticalLayout.addWidget(self.webEngineView) # Añade la vista web al layout vertical self.verticalLayout.setContentsMargins(0, 0, 0, 0) # Establece los márgenes del layout self.webEngineView.setUrl(QtCore.QUrl("https://www.mitele.es/")) # Establece la URL de la vista web self.webEngineView.setObjectName("webEngineView") # Establece el nombre del objeto de la vista web MainWindow.setCentralWidget(self.centralwidget) # Establece el widget central de la ventana principal icon_path = os.path.join(os.path.dirname(sys.argv[0]), "iconos/mitele.ico") # Obtiene la ruta del icono MainWindow.setWindowIcon(QtGui.QIcon(icon_path)) # Establece el icono de la ventana principal if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) # Crea una instancia de la aplicación Qt myappid = 'entreunosyceros.tv.subproduct.01' # Identificador de la aplicación if sys.platform == 'win32': # Si el sistema operativo es Windows import ctypes ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid) # Establece el identificador de la aplicación MainWindow = QtWidgets.QMainWindow() # Crea una instancia de la ventana principal ui = Ui_MainWindow() # Crea una instancia de la clase de interfaz de usuario ui.setupUi(MainWindow) # Configura la interfaz de usuario MainWindow.show() # Muestra la ventana principal sys.exit(app.exec_()) # Ejecuta la aplicación y espera a que se cierre
Descarga todo el proyecto desde GitHub
Y esto se hará con todos los servicios o páginas web que queramos ver desde el escritorio, sin necesidad de utilizar el navegador web. Hay que decir que al no utilizar el navegador web, no tendremos disponible el bloqueador de anuncios, por lo que los anuncios de las páginas, habrá que tragarselos.
Todo el código necesario para poner a funcionar esta aplicación Python, se puede encontrar en el repositorio de GitHub en el que alojé el proyecto. Además de todo el código, en el repositorio incluí también el archivo TV_entreunosyceros.desktop. Este lo creeo para que se guarde en la carpeta ~/local/share/applications y así poder tener la aplicación disponible desde el menú de aplicaciones de Ubuntu. En este archivo abrá que cambiar la ruta a al archivo.py y al icono, ya que yo lo tengo todo guardado en la ruta «/var/www/html/webapp/«, y cada uno deberá modificarla por la que utilice.

En el repositorio también he subido los archivos .ico de los servicios que se han incluido. Pero como siempre, todo esto es susceptible de que cada uno cambie lo que quiera.
Y bueno, con todo esto, creo que la persona que me pidió una solución para poder seguir trabajando con un millar de pestañas abiertas. Mientras reproduce contenido, puede tener aquí una «posible» solución. Por que como ya dije, todo depende mucho de las capacidades de su equipo.
A tener en cuenta!!
Quien esté pensando en que esto es la panacea, que se olvide. Claro está que se pueden mejorar estas web apps y que actúen como lo hacen con el navegador, pero no con los sencillos pasos que se incluyen en este proyecto. Esto va a servir para tener aplicaciones como YouTube, Pluto TV, Twitch… pero no se pueden descargar archivos, no guarda las contraseñas ni se pueden instalar extensiones.
Lo mejor de esto es que, justamente por ser sólo un visor básico y limitado, la aplicación web consumirá menos recursos. Esto es algo muy básico para que el ordenador no sufra demasiado.