Creaci贸n de aplicaciones GUI de Python con wxPython

    Introducci贸n

    En este tutorial, aprenderemos a usar wxPython biblioteca para desarrollar interfaces gr谩ficas de usuario (GUI) para aplicaciones de escritorio en Python. La GUI es la parte de su aplicaci贸n que permite al usuario interactuar con su aplicaci贸n sin tener que escribir comandos, puede hacer pr谩cticamente todo con un clic del mouse.

    Algunas de las alternativas populares de Python para desarrollar una GUI incluyen Tkintery pyqt. Sin embargo, en este tutorial, aprenderemos sobre wxPython.

    Antes de seguir adelante, existen algunos requisitos previos para este tutorial. Debe tener un conocimiento b谩sico de la sintaxis de Python y / o haber realizado al menos programaci贸n de nivel principiante en alg煤n otro idioma. Aunque puede seguirlo, incluso si no cumple con estos criterios, es posible que algunas partes sean un poco complejas. Si es as铆, no dude en pedir aclaraciones en los comentarios.

    Instalaci贸n

    El proceso de instalaci贸n de wxPython es bastante sencillo, aunque difiere ligeramente seg煤n el sistema que est茅 utilizando.

    Mac y Windows

    WxPython es bastante f谩cil de instalar en Mac y Windows usando pepita gerente de empaquetaci贸n. Si tiene pip instalado en su sistema, ejecute el siguiente comando para descargar e instalar wxPython:

    $ pip install wxpython
    

    Linux

    Para Linux, el procedimiento podr铆a ser un poco complicado, ya que tiene muchas bibliotecas de requisitos previos que deben instalarse. Recomendar铆a intentar ejecutar los siguientes dos comandos en una secuencia:

    # Command 1
    $ sudo apt-get install dpkg-dev build-essential python2.7-dev python3.5-dev python3.6-dev libgstreamer-plugins-base1.0-dev libnotify-dev libwebkitgtk-3.0-dev libwebkit-dev libwebkitgtk-dev libjpeg-dev libtiff-dev libgtk2.0-dev libsdl1.2-dev libgstreamer-plugins-base0.10-dev freeglut3 freeglut3-dev
    
    # Command 2
    $ pip install --upgrade --pre -f https://wxpython.org/Phoenix/snapshot-builds/ wxPython
    

    Sin embargo, si estos no funcionan, tendr谩 que instalar manualmente estas bibliotecas, una lista de las cuales se menciona en la secci贸n “Requisitos previos” de WxPython Repositorio de Github.

    Ejemplos de creaci贸n de GUI con wxPython

    En esta secci贸n, nos ensuciaremos las manos con wxPython y crearemos una aplicaci贸n b谩sica de manipulaci贸n de cadenas con algunas funcionalidades b谩sicas, como contar el n煤mero de palabras, mostrar la frecuencia de cada palabra, palabra m谩s repetida, etc.

    Antes de seguir adelante, crearemos una aplicaci贸n esqueleto muy simple, que usaremos como punto de partida en los pr贸ximos ejemplos para implementar funcionalidades GUI m谩s avanzadas.

    Sin m谩s pre谩mbulos, comencemos. A continuaci贸n se muestra el esqueleto o la estructura b谩sica de una aplicaci贸n GUI construida con wxPython. Lo cambiaremos m谩s en la siguiente secci贸n para que est茅 orientado a objetos para una funcionalidad adicional.

    import wx
    
    # Creates an App object which runs a loop to display the
    # GUI on the screen
    myapp = wx.App()
    
    # Initialises a frame that the user would be able to
    # interact with
    init_frame = wx.Frame(parent=None, title="Word Play")
    
    # Display the initialised frame on screen
    init_frame.Show()
    
    # Run a loop on the app object
    myapp.MainLoop()
    

    Si el bucle no se ejecuta (es decir, el app.MainLoop() llamada), el marco aparecer谩 en la pantalla durante una fracci贸n de segundo, e incluso antes de que pueda verlo, desaparecer谩. Esta funci贸n asegura que el marco permanece visible en la pantalla, hasta que el usuario sale del programa, y 鈥嬧媗o hace ejecutando el marco en un bucle.

    Nota: Mientras ejecutaba esto en una Mac, recib铆 el siguiente error cuando ejecut茅 mi c贸digo usando python filename.py comando en la terminal:

    This program needs access to the screen. Please run with a Framework build of python, and only when you are logged in on the main display of your Mac.
    

    Para deshacerse de esto, simplemente use pythonw en vez de python en el comando anterior.

    Una vez que se ejecuta el programa, deber铆a ver la siguiente ventana en blanco en su pantalla:

    C贸digo orientado a objetos

    Antes de agregar funcionalidad a nuestro c贸digo, primero modular茅moslo creando clases y funciones, para que se vea m谩s limpio y sea m谩s f谩cil extenderlo. La funcionalidad del siguiente c贸digo es la misma que antes, sin embargo, se ha refactorizado para implementar conceptos de programaci贸n orientada a objetos.

    import wx
    import operator
    
    # We make a class for frame, so that each time we
    # create a new frame, we can simply create a new
    # object for it
    
    class WordPlay(wx.Frame):
        def __init__(self, parent, title):
            super(WordPlay, self).__init__(parent, title=title)
            self.Show()
    
    def main():
        myapp = wx.App()
        WordPlay(None, title="Word Play")
        myapp.MainLoop()
    
    main()
    

    En el script de arriba, creamos una clase WordPlay que hereda el wxFrame clase. El constructor del WordPlay la clase acepta dos par谩metros: parent y title. Dentro del constructor hijo, el constructor de la clase padre para el wxPython se llama la clase y el parent y title se le pasan atributos. Finalmente, el show se llama al m茅todo para mostrar el marco. En el main() m茅todo, el objeto de WordPlay se crea la clase.

    El c贸digo ahora parece mucho m谩s estructurado y limpio; es m谩s f谩cil de entender y se pueden agregar m谩s funcionalidades al c贸digo anterior.

    A帽adiendo funcionalidades

    Agregaremos funcionalidades una a la vez para evitar confusiones sobre qu茅 parte del c贸digo se agrega para qu茅 funcionalidad en particular. Lo que queremos en nuestra aplicaci贸n b谩sica es un cuadro de texto donde podamos agregar texto, y luego unos botones para realizar diferentes funciones en ese texto, como calcular el n煤mero de palabras que contiene, la frecuencia de cada palabra, etc., seguido del la salida se muestra en la pantalla de nuestra aplicaci贸n.

    Comencemos agregando un cuadro de texto a nuestra aplicaci贸n en el que podemos agregar nuestro texto.

    # Some of the code will be the same as the one above,
    # so make sure that you understand that before moving
    # to this part
    
    import wx
    import operator
    
    # We make a class for frame, so that each time we create a new frame,
    # we can simply create a new object for it
    
    class WordPlay(wx.Frame):
        def __init__(self, parent, title):
            super(WordPlay, self).__init__(parent, title=title)
            self.widgets()
            self.Show()
    
        # Declare a function to add new buttons, icons, etc. to our app
        def widgets(self):
            text_box = wx.BoxSizer(wx.VERTICAL) # Vertical orientation
    
            self.textbox = wx.TextCtrl(self, style=wx.TE_RIGHT)
            text_box.Add(self.textbox, flag=wx.EXPAND | wx.TOP | wx.BOTTOM, border=5)
    
            grid = wx.GridSizer(5, 5, 10, 10) # Rows, columns, vertical gap, horizontal gap
            text_box.Add(grid, proportion=2, flag=wx.EXPAND)
    
            self.SetSizer(text_box)
    
    def main():
        myapp = wx.App()
        WordPlay(None, title="Word Play")
        myapp.MainLoop()
    
    main()
    

    Como puede ver, hemos agregado una nueva funci贸n llamada widgets() arriba, y ha sido llamado en el WordPlay constructor de la clase. Su prop贸sito es agregar nuevos widgets a nuestra pantalla; sin embargo, en nuestro caso solo nos interesa agregar un widget, es decir, un cuadro de texto donde podemos agregar algo de texto.

    Ahora entendamos algunas cosas importantes que est谩n sucediendo dentro de este widgets() funci贸n. los BoxSizer() El m茅todo, como su nombre indica, controla el tama帽o de los widgets, as铆 como su posici贸n (relativa o absoluta). los wx.VERTICAL especifica que queremos una orientaci贸n vertical para este widget. TextCtrl b谩sicamente agrega un peque帽o cuadro de texto en nuestro actual desde, donde el usuario puede ingresar una entrada de texto. los GridSizer() El m茅todo nos ayuda a crear una estructura similar a una tabla para nuestra ventana.

    Muy bien, veamos c贸mo se ve nuestra aplicaci贸n ahora.

    Ahora se puede ver un cuadro de texto en la ventana de nuestra aplicaci贸n.

    Avancemos m谩s y agreguemos dos botones a nuestra aplicaci贸n, uno para contar la cantidad de palabras en el texto y el segundo para mostrar la palabra m谩s repetida. Lo lograremos en dos pasos, primero agregaremos dos botones nuevos y luego agregaremos controladores de eventos a nuestro programa que nos dir谩n en qu茅 bot贸n ha hecho clic el usuario, junto con el texto ingresado en el cuadro de texto, de modo que un Se puede realizar una acci贸n espec铆fica en la entrada.

    Agregar botones es bastante simple, solo requiere agregar un c贸digo adicional a nuestra funci贸n “widgets”. En el bloque de c贸digo a continuaci贸n, solo mostraremos la funci贸n de widgets actualizada; el resto del c贸digo permanece igual.

    # Adding buttons to our main window
    
    def widgets(self):
        text_box = wx.BoxSizer(wx.VERTICAL)
    
        self.textbox = wx.TextCtrl(self, style=wx.TE_RIGHT)
        text_box.Add(self.textbox, flag=wx.EXPAND | wx.TOP | wx.BOTTOM, border=5)
    
        grid = wx.GridSizer(2, 5, 5) # Values have changed to make adjustments to button positions
        button_list = ['Count Words', 'Most Repeated Word'] # List of button labels
    
        for lab in button_list:
            button = wx.Button(self, -1, lab) # Initialise a button object
            grid.Add(button, 0, wx.EXPAND) # Add a new button to the grid with the label from button_list
    
        text_box.Add(grid, proportion=2, flag=wx.EXPAND)
    
        self.SetSizer(text_box)
    

    Como puede ver, ahora tambi茅n se han agregado dos nuevos botones a nuestra ventana principal.

    Agregar un controlador de eventos

    La interfaz de nuestra aplicaci贸n ya est谩 lista, todo lo que tenemos que hacer ahora es agregar controladores de eventos para realizar acciones espec铆ficas al hacer clic en los botones. Para eso tendremos que crear una nueva funci贸n y agregar una l铆nea adicional de c贸digo en la funci贸n de widgets. Comencemos escribiendo nuestra funci贸n.

    # Declare an event handler function
    
    def event_handler(self, event):
        # Get label of the button clicked
        btn_label = event.GetEventObject().GetLabel()
    
        # Get the text entered by user
        text_entered = self.textbox.GetValue()
    
        # Split the sentence into words
        words_list = text_entered.split()
    
        # Perform different actions based on different button clicks
        if btn_label == "Count Words":
            result = len(words_list)
        elif btn_label == "Most Repeated Word":
            # Declare an empty dictionary to store all words and
            # the number of times they occur in the text
            word_dict = {}
    
            for word in words_list:
                # Track count of each word in our dict
                if word in word_dict:
                    word_dict[word] += 1
                else:
                    word_dict[word] = 1
    
                # Sort the dict in descending order so that the
                # most repeated word is at the top
                sorted_dict = sorted(word_dict.items(),
                                    key=operator.itemgetter(1),
                                    reverse=True)
    
                # First value in the dict would be the most repeated word
                result = sorted_dict[0]
    
        # Set the value of the text box as the result of our computation
        self.textbox.SetValue(str(result))
    

    La l贸gica detr谩s de la funci贸n “Palabra m谩s repetida” es que primero ejecutamos un ciclo que recorre la palabra de la lista de todas las palabras. Luego verifica si esa palabra en particular ya existe en el diccionario o no; si lo hace, significa que se est谩 repitiendo y su valor se incrementa en uno cada vez que reaparece la palabra. De lo contrario, si no existe en el diccionario, significa que ha aparecido en la oraci贸n por primera vez y su valor de ‘ocurrencia’ debe establecerse en 1. Por 煤ltimo, ordenamos el diccionario (similar a la clasificaci贸n de listas de Python ) en orden descendente para que la palabra con el valor m谩s alto (frecuencia) salga en la parte superior, que luego podemos mostrar.

    Muy bien, ahora que hemos escrito el c谩lculo / acci贸n que debe realizarse cuando se hace clic en un bot贸n espec铆fico, “vinculemos” esa acci贸n a ese bot贸n en particular. Para eso, tendremos que modificar ligeramente nuestro widgets funci贸n.

    # Only one line needs to be added in the "for loop" of
    # our widgets function, so that's all we're showing
    for lab in button_list:
        button = wx.Button(self, -1, lab)
        self.Bind(wx.EVT_BUTTON, self.event_handler, button)
        grid.Add(button, 0, wx.EXPAND)
    

    En el c贸digo anterior, el self.Bind La llamada es donde ocurre el enlace. Lo que hace es que vincula una acci贸n en particular a un bot贸n espec铆fico, de modo que cuando hace clic en ese bot贸n, se realiza una acci贸n espec铆fica vinculada a 茅l. En nuestro caso particular, solo tenemos una funci贸n de controlador de eventos, que maneja ambas acciones al verificar en tiempo de ejecuci贸n en qu茅 bot贸n se hizo clic a trav茅s de la propiedad ‘etiqueta’ y luego realizar la acci贸n vinculada. Entonces en el self.Bind call vinculamos todos nuestros botones a la 煤nica funci贸n ‘event_handler’.

    Muy bien, nuestro c贸digo ahora est谩 completo. Probemos nuestras dos funciones y veamos si todo funciona como se esperaba.

    En el primer paso, como se muestra a continuaci贸n, ingresamos una cadena en el cuadro de texto:

    A continuaci贸n, si hacemos clic en el bot贸n “Contar palabras”, deber铆a ver “7” en el cuadro de texto, ya que hab铆a 7 palabras en la cadena.

    隆Hasta aqu铆 todo bien!

    Ahora escribamos otra cadena en el cuadro de texto, como se muestra en la siguiente figura:

    Ahora, si hacemos clic en el bot贸n “Palabra m谩s repetida”, ver谩 las palabras m谩s repetidas en el cuadro de texto, junto con su frecuencia de aparici贸n, como se muestra a continuaci贸n:

    隆Funciona perfectamente!

    Solo hemos agregado dos funciones, pero el prop贸sito era mostrarle c贸mo est谩n conectados todos estos componentes, puede agregar tantas funcionalidades como desee simplemente escribiendo funciones adicionales para ellos. Adem谩s, este tutorial no se centr贸 mucho en la est茅tica. Hay muchos widgets disponibles en wxPython para embellecer su programa ahora que ha adquirido los conocimientos b谩sicos del kit de herramientas.

    Conclusi贸n

    Para resumir, aprendimos que wxPython se usa popularmente para desarrollar aplicaciones de escritorio basadas en GUI en Python, y que Python tambi茅n tiene otras alternativas interesantes para ello. Revisamos los comandos para descargarlo e instalarlo en todos los sistemas operativos populares. Por 煤ltimo, aprendimos c贸mo hacer una aplicaci贸n modular usando wxPython que se puede extender f谩cilmente, como se puede ver en este tutorial donde construimos una aplicaci贸n b谩sica de esqueleto y agregamos m谩s funciones paso a paso.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *