[PYTHON] Création d'outils GUI avec pyinstaller

J'ai créé un outil à distribuer en interne pour rationaliser le prétraitement des données. Créé pour être utilisé par les utilisateurs de Windows. Pour le moment, j'ai lu le fichier csv et créé quelque chose qui génère des comptes, des moyennes, des distributions, etc.

Environnement de travail

Mac OSX 10.9.5 Core i7(64bit) Python 2.7.9

Bibliothèque utilisée

Éléments d'entrée sur l'écran GUI

Code de référence

Tout ce que vous avez à faire est de créer un cadre pour l'entrée avec Tkinter, de le traiter avec des pandas et de le sortir.

Tout d'abord, le code côté GUI est le suivant.

python


# coding: utf-8

from Tkinter import *
import ttk
import tkFileDialog
import tkMessageBox
import os,sys
import pandas as pd
from do_pivot import main

# global path name(store file path)
path_name = "."

def close_window():
    root.destroy()

def load_file(_entry):
    global path_name
    try:
        filename = tkFileDialog.askopenfilename(initialdir=path_name)
        if filename is not None:
            path_name = os.path.dirname(filename) #Définir le chemin actuel sur la valeur par défaut
            _entry.set(filename)
    except ValueError, e:
        pass

def pivot(*args):
    try:
        result_dic = main(input_filename.get(), funcs.get().encode('utf-8'), \
                          row_columns.get().encode('utf-8'), col_columns.get().encode('utf-8'))
        for (row_label,col_label, s_func), pivoted_data in result_dic.items():
            pivoted_data.to_csv(output_filename.get()+row_label+u'-'+col_label+u'-'+u'_pivot('+s_func+u').csv', encodeing='shift-jis')
        tkMessageBox.showinfo(u'showinfo', u'Réussite')
    except Exception, e:
        import traceback
        print traceback.format_exc()
        tkMessageBox.showerror(u'showerror',u'Une erreur est survenue')

def set_save_file_name(_entry):
    global path_name
    try:
        filename = tkFileDialog.asksaveasfilename(initialfile='pivot_result_', defaultextension='' ,initialdir=path_name)
        if filename is not None:
            path_name = os.path.dirname(filename)
            _entry.set(filename)
    except ValueError:
        pass

if __name__=='__main__':
    root = Tk()
    root.title(u"pivot data")

    #Définition du cadre
    mainframe = ttk.Frame(root, padding="3 3 12 12")
    mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
    mainframe.columnconfigure(0, weight=1)
    mainframe.rowconfigure(0, weight=1)

    #Définition variable
    input_filename = StringVar()
    output_filename = StringVar()
    row_columns = StringVar()
    col_columns = StringVar()
    funcs = StringVar()

    #Réglage de la valeur initiale
    row_columns.set('demogra,class')
    col_columns.set('Élément de satisfaction 1, élément de satisfaction 2, élément de satisfaction 3, élément de satisfaction 4')
    funcs.set('Nombre, moyenne')

    ttk.Label(mainframe, text=u"Fichier de résultats du questionnaire").grid(column=1, row=1, sticky=W)
    input_filename_entry = ttk.Entry(mainframe, width=20, textvariable=input_filename)
    input_filename_entry.grid(column=2, row=1, sticky=(W, E))
    ttk.Button(mainframe, text=u'Recherche de fichier', command= lambda: load_file(input_filename)).grid(column=3, row=1,sticky=E)

    ttk.Label(mainframe, text=u"Nom du fichier de base de sortie").grid(column=1, row=2, sticky=W)
    output_filename_entry = ttk.Entry(mainframe, width=20, textvariable=output_filename)
    output_filename_entry.grid(column=2, row=2, sticky=(W, E))
    ttk.Button(mainframe, text=u'Recherche de fichier', command= lambda: set_save_file_name(output_filename)).grid(column=3, row=2, sticky=E)

    ttk.Label(mainframe, text=u"Colonne (s) de segment").grid(column=1, row=3, sticky=W)
    row_columns_entry = ttk.Entry(mainframe, width=20, textvariable=row_columns)
    row_columns_entry.grid(column=2, row=3, sticky=(W, E))
    
    ttk.Label(mainframe, text=u"Colonnes à agréger (s)").grid(column=1, row=4, sticky=W)
    col_columns_entry = ttk.Entry(mainframe, width=20, textvariable=col_columns)
    col_columns_entry.grid(column=2, row=4, sticky=(W, E))

    ttk.Label(mainframe, text=u"Méthode (s) d'agrégation").grid(column=1, row=5, sticky=W)
    funcs_entry = ttk.Entry(mainframe, width=20, textvariable=funcs)
    funcs_entry.grid(column=2, row=5, sticky=(W, E))

    # calculate button
    ttk.Button(mainframe, text=u'Calculate', command=pivot).grid(column=2,row=6, sticky=E)

    # close button
    ttk.Button(mainframe, text=u'Exit', command=close_window).grid(column=3,row=6)

    for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=6)

    input_filename_entry.focus()
    root.bind('<Return>', pivot)

    root.mainloop()

Ensuite, le traitement du pivot dans les pandas appelés du côté de l'interface graphique est le suivant.

python


# coding: utf-8

import pandas as pd
import os
import numpy as np

def get_data(ifname):
    if '.csv' in ifname:
        return pd.read_csv(ifname, delimiter=r',', encoding='shift-jis')
    elif '.tsv' in ifname:
        return pd.read_csv(ifname, delimiter=r'\t', encoding='shift-jis')

def calculate_pivot(df_data, row_label, col_label, agg_func):
    try:
        df_data[col_label].astype(np.float64)
        return df_data[[row_label, col_label]].groupby(row_label).aggregate(agg_func)
    except Exception, e:
        print e
        return df_data[[row_label, col_label]].pivot_table(rows=row_label, cols=col_label, aggfunc=agg_func, fill_value=0)

def select_pivot_func(str_funcs):
    avg = (u'average',u'avg',u'mean',u'moyenne',u'moyenne値')
    cnt = (u'count',u'compter',u'compter数',u'compter値',u'Nombre de fois')
    total_sum = (u'sum',u'total',u'total',u'Total',u'total値')
    med = (u'median',u'Médian',u'Central')
    sv = (u'Distribué',u'var',u'variance')
    sd = (u'écart-type',u'deviation',u'sd')

    func_list = []
    except_len_list = []
    for t_func in replace_comma(str_funcs):
        t_func = t_func.strip()
        if t_func in cnt:
            func_list.append((t_func,[len]))
        elif t_func in avg:
            except_len_list = add_func(except_len_list, t_func, np.mean)
        elif t_func in total_sum:
            except_len_list = add_func(except_len_list, t_func, np.sum)
        elif t_func in med:
            except_len_list = add_func(except_len_list, t_func, np.median)
        elif t_func in sv:
            except_len_list = add_func(except_len_list, t_func, np.var)
        elif t_func in sd:
            except_len_list = add_func(except_len_list, t_func, np.std)
    return func_list+except_len_list

def add_func(except_len_list, t_func, func):
    if len(except_len_list)!=0:
        except_len_list[0] = \
            (except_len_list[0][0]+','+t_func, except_len_list[0][1]+[func])
    else:
        except_len_list.append((t_func,[func]))
    return except_len_list

def replace_comma(str_data):
    str_res = [ s.decode('utf-8') for s in str_data.replace('、', ',').strip().split(',')]
    return map(lambda s:s.strip(), str_res)

def do_pivot(df_data ,row_labels, col_labels, str_funcs):
    pivot_dic = {}
    for s_func, func in select_pivot_func(str_funcs):
        for row_label in replace_comma(row_labels):
            for col_label in replace_comma(col_labels):
                try:
                    pivot_dic[(row_label,col_label,s_func)] = \
                        calculate_pivot(df_data, row_label, col_label, func)
                except Exception, e:
                    #print "miss:", s_func, col_label
                    print e
    #for (row_label,col_label, s_func), pivot_q in pivot_dic.items():
    #    print type(row_label), row_label
    #    pivot_q.to_csv( row_label+u'-'+col_label+u'-'+u'_pivot('+s_func+u').csv')
    return pivot_dic

def main(ifname, str_funcs, str_row_labels, str_col_labels):
    df_raw_data = get_data(ifname)

    return  do_pivot(df_raw_data, str_row_labels, str_col_labels, str_funcs)
    
if __name__ == '__main__':
    basepath = os.getcwd()
    ifpath = basepath + '/'
    ofpath = basepath + '/'
    ifname = ifpath + '/test.tsv'

    ###Obtenez des données brutes
    df_raw_data = get_data(ifname)
    df_raw_data['test'] = np.random.randint(5,size=len(df_raw_data.ix[:,0]))

    #Objet Pipod
    str_funcs = 'Nombre, moyenne,Distribué'
    col_labels = "Q4_s, Q5_s,Q6_s,Q7_s,Q8_s,Q9_s,test"
    row_labels = "class,demogra"

    do_pivot(df_raw_data, row_labels, col_labels, str_funcs)

Je pense qu'il y a beaucoup de choses à faire, comme la reconnaissance automatique des codes de caractères, les méthodes d'agrégation et la génération dynamique de cases à cocher de ligne et de colonne. Cependant, comme il s'agit d'un outil interne, je me demande s'il est correct de le faire w

Après cela, tapez simplement la commande suivante pour créer un fichier exécutable dans le répertoire dist.

python


% pyinstaller --onefile --windowed your_python_file.py 

--onefile combinera tous les fichiers associés dans un seul fichier, et --windowed est une option pour empêcher le terminal de se lancer lors de l'exécution.

écran

L'écran créé par le code ci-dessus ressemble à ceci: GUI.png

commentaire

Sentir que je l'ai fait Il y avait une partie gênante autour du code de caractère. Je pense qu'il est plus facile de traiter en Unicode selon Windows. Tout le reste est absorbé par pyinstaller, donc c'est très facile.

De plus, si vous souhaitez créer un outil GUI, vous devez vérifier la licence. Les sites suivants ont été utiles.

Si vous faites une erreur, veuillez nous contacter.

Recommended Posts

Création d'outils GUI avec pyinstaller
Programmation GUI à l'aide de kivy ~ Partie 5 Création de boutons avec des images ~
Récapitulatif des outils d'exploitation de l'interface graphique Windows avec Python
Création de "Web Tools" BINGO avec Python (Table of Contents)
Créer un œuf avec python
[GUI en Python] PyQt5-Layout management-
Créer une interface graphique aussi facilement que possible avec python [édition tkinter]
[GUI avec Python] PyQt5-Préparation-
Créer des plug-ins asynchrones avec neovim
[GUI avec Python] PyQt5 -Paint-
[GUI avec Python] PyQt5 -Widget II-
Créer un arbre déterminé avec scikit-learn
Faisons une interface graphique avec python.
Créer un serveur Flask avec Docker
[GUI avec Python] PyQt5-La première étape-
Application GUI facile avec Tkinter Text
[GUI en Python] PyQt5-Glisser-déposer-
Création d'interface graphique avec Pyside2 <niveau maternelle>
Commandes lors de la création de SNS avec Django
[GUI avec Python] PyQt5-Widget personnalisé-
Créer un exe Scrapy avec Pyinstaller
Dessinez un graphique avec l'interface graphique PySimple
[Python] Création de plusieurs fenêtres avec Tkinter
Création d'un fichier exe avec Python PyInstaller: le PC se fige dans le traitement parallèle