Creación de Interfaz Gráfica con wxPython

Primero, realizaremos una interfaz gráfica con solo 4 líneas de código usando la librería wx

In [1]:
import wx
app = wx.App()
wx.Frame(None, title="Hello World").Show()
app.MainLoop()
Out[1]:
0

A continuación, se muestra la interfaz simple realizada:

En segundo lugar, realizaremos una Interfáz para abrir bases de datos en excel, ordenarlos y gráficar.

Importamos las librerías adicionales a utilizar

In [5]:
import wx
import pandas as pd
import matplotlib.pyplot as plt

Creamos la clase MyFrame la cual contiene funciones para la configuración de botones, abrir archivos Excel, Ordenar datos y Graficar.

In [3]:
class MyFrame(wx.Frame):

    def __init__(self): ## Ver Figura 1
        wx.Frame.__init__(self, None, title='Excel File Reader',size=(800,600))
        logo = wx.Icon("./img/logo_jpi.png")
        self.SetIcon(logo)

        # Global Variables
        self.sortAsc = None

        self.my_text = wx.TextCtrl(self, style=wx.TE_MULTILINE)
        self.my_text.SetFont(wx.Font(10, family = wx.DEFAULT, style = wx.NORMAL, weight = wx.BOLD, faceName = 'Consolas'))

        # Buttons
        btn1 = wx.Button(self, label='Open Excel File')
        btn1.Bind(wx.EVT_BUTTON, self.onOpen)
        #
        btn2 = wx.Button(self, label='Sort',size=(70, 30))
        btn2.Bind(wx.EVT_BUTTON, self.sorter)
        #
        btn3 = wx.Button(self, label='Graph',size=(70, 30))
        btn3.Bind(wx.EVT_BUTTON, self.charts)

        # Sizers
        vbox = wx.BoxSizer(wx.VERTICAL)
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        # Horizontal Sizer
        hbox.Add(btn2, flag=wx.LEFT,border=5)
        hbox.Add(btn3, flag=wx.LEFT,border=5)
        # Vertical Sizer
        vbox.Add(self.my_text, 1, wx.ALL|wx.EXPAND)
        vbox.Add(btn1, 0, wx.ALL|wx.CENTER, 5)
        vbox.Add(hbox, flag=wx.CENTER, border=5)
        vbox.Add((-1, 5))
        
        self.SetSizer(vbox)
        self.Show()

    def onOpen(self, event): ## Ver Figura 2
        wildcard = "Excel files (*.xlsx)|*.xlsx"
        dialog = wx.FileDialog(self, "Open Excel Files", wildcard=wildcard,
                               style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
        # If click on cancel
        if dialog.ShowModal() == wx.ID_CANCEL:
            return
        # if path exists
        path = dialog.GetPath()
        if os.path.exists(path):
            my_sheet = 'BAS_LIM_DISTRITOS' # change it to your sheet name
            cols={'ID','NOMBDIST','NOMBPROV','NOMBDEP',"SHAPE_AREA"}
            # reading data with pandas
            self.df = pd.read_excel(path, sheet_name = my_sheet, usecols=cols)
            self.my_text.WriteText(self.df[:100].to_string(index=False,col_space=20,
            max_colwidth=15,justify='center')+'\n')#,col_space=30,max_colwidth=25
    
    def sorter(self, event): ## Ver Figura 4
        # Cheching dataframe
        try:
            self.df.head()
        except:
            print("No se ha cargado el archivo Excel")
            return
        # Clearing current text
        self.my_text.Clear()
        # 
        if self.sortAsc != None:
            # Changing from True to False and vice versa
            if self.sortAsc == True:
                self.sortAsc = False
            elif self.sortAsc == False:
                self.sortAsc = True
            else:
                print("No es None, True ni False!")
        else:
            self.sortAsc = True
        # Sorting in ascending or descending way
        df = self.df.sort_values('SHAPE_AREA',ascending=self.sortAsc)
        self.my_text.WriteText(df[:30].to_string(index=False,col_space=20,max_colwidth=15,justify='center')+'\n')

    def charts(self, event): ## Ver Figura 5
        # Cheching dataframe
        try:
            self.df.head()
        except:
            print("No se ha cargado el archivo Excel.")
            return
        # Creating empty lists
        areas = []
        depas = []
        # Loop for each department
        for depa in  self.df['NOMBDEP'].unique():
            temp=self.df.loc[self.df['NOMBDEP'] == depa]
            areas.append(sum(temp["SHAPE_AREA"]))
            depas.append(depa)
        # Creating dataframe from lists
        df_dep = pd.DataFrame(list(zip(depas,areas)),columns =['DEPA', 'AREA'])
        df_dep = df_dep.sort_values('AREA')
        # Plotting a pie chart
        fig1, ax1 = plt.subplots()
        ax1.title.set_text('Gráfico Circular')
        fig1.canvas.set_window_title('Gráfico Circular')
        ax1.pie(df_dep['AREA'], labels=df_dep['DEPA'], autopct='%1.1f%%', 
                startangle=90,textprops={'fontsize': 8})
        ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.
        plt.show()
      

Ejecutamos la aplicación

In [6]:
app = wx.App()# False
frame = MyFrame()
app.MainLoop()
Out[6]:
0

Figura 1: Vista de la interfáz y botones.

Figura 2: Vista al ejecutar la función para abrir archivo Excel.

Figura 3: Vista después de abrir el archivo.

Figura 4: Vista después de ordenar según el área.

Figura 5: Vista del gráfico circular.