[PYTHON] Erstellen von GUI-Tools mit Pyinstaller

Ich habe ein Tool zur internen Verteilung entwickelt, um die Datenvorverarbeitung zu optimieren. Erstellt für Windows-Benutzer. Zur Zeit habe ich die CSV-Datei gelesen und etwas erstellt, das Zählungen, Durchschnittswerte, Verteilungen usw. ausgibt.

Arbeitsumgebung

Mac OSX 10.9.5 Core i7(64bit) Python 2.7.9

Bibliothek verwendet

Geben Sie Elemente auf dem GUI-Bildschirm ein

Referenzcode

Sie müssen lediglich einen Rahmen für die Eingabe mit Tkinter erstellen, ihn mit Pandas verarbeiten und ausgeben.

Erstens lautet der Code auf der GUI-Seite wie folgt.

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) #Setzen Sie den aktuellen Pfad auf Standard
            _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'Erfolgreiche Fertigstellung')
    except Exception, e:
        import traceback
        print traceback.format_exc()
        tkMessageBox.showerror(u'showerror',u'Ein Fehler ist aufgetreten')

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")

    #Definition des Rahmens
    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)

    #Variablendefinition
    input_filename = StringVar()
    output_filename = StringVar()
    row_columns = StringVar()
    col_columns = StringVar()
    funcs = StringVar()

    #Anfangswerteinstellung
    row_columns.set('demogra,class')
    col_columns.set('Zufriedenheitspunkt 1, Zufriedenheitspunkt 2, Zufriedenheitspunkt 3, Zufriedenheitspunkt 4')
    funcs.set('Anzahl, Durchschnitt')

    ttk.Label(mainframe, text=u"Ergebnisdatei des Fragebogens").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'Dateisuche', command= lambda: load_file(input_filename)).grid(column=3, row=1,sticky=E)

    ttk.Label(mainframe, text=u"Name der Basisdatei ausgeben").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'Dateisuche', command= lambda: set_save_file_name(output_filename)).grid(column=3, row=2, sticky=E)

    ttk.Label(mainframe, text=u"Segmentspalte (n)").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"Zu aggregierende Spalten.").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"Aggregationsmethode (n)").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()

Als nächstes ist die Pivot-Verarbeitung in Pandas, die von der GUI-Seite aufgerufen werden, wie folgt.

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'durchschnittlich',u'durchschnittlich値')
    cnt = (u'count',u'Anzahl',u'Anzahl数',u'Anzahl値',u'Anzahl')
    total_sum = (u'sum',u'total',u'gesamt',u'Gesamt',u'gesamt値')
    med = (u'median',u'Median',u'Zentral')
    sv = (u'Verteilt',u'var',u'variance')
    sd = (u'Standardabweichung',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'

    ###Rohdaten abrufen
    df_raw_data = get_data(ifname)
    df_raw_data['test'] = np.random.randint(5,size=len(df_raw_data.ix[:,0]))

    #Pipod Gegenstand
    str_funcs = 'Anzahl, Durchschnitt,Verteilt'
    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)

Ich denke, dass viele Dinge getan werden müssen, wie die automatische Erkennung von Zeichencodes, Aggregationsmethoden und die dynamische Generierung von Kontrollkästchen für Zeilen und Spalten. Da es sich jedoch um ein internes Tool handelt, frage ich mich, ob dies in Ordnung ist

Geben Sie danach einfach den folgenden Befehl ein, um eine ausführbare Datei im Verzeichnis dist zu erstellen.

python


% pyinstaller --onefile --windowed your_python_file.py 

--onefile kombiniert alle zugehörigen Dateien zu einer Datei. --windowed ist eine Option, um zu verhindern, dass das Terminal zur Laufzeit gestartet wird.

Bildschirm

Der mit dem obigen Code erstellte Bildschirm sieht folgendermaßen aus: GUI.png

Kommentar

Ich habe das Gefühl, dass ich es geschafft habe. Es gab einen problematischen Teil um den Zeichencode. Ich denke, es ist einfacher, in Unicode gemäß Windows zu verarbeiten. Alles andere wird vom Pyinstaller absorbiert, daher ist es sehr einfach.

Wenn Sie ein GUI-Tool erstellen möchten, sollten Sie auch die Lizenz überprüfen. Die folgenden Websites waren hilfreich.

Wenn Sie einen Fehler machen, kontaktieren Sie uns bitte.

Recommended Posts

Erstellen von GUI-Tools mit Pyinstaller
GUI-Programmierung mit kivy ~ Teil 5 Erstellen von Schaltflächen mit Bildern ~
Zusammenfassung der Tools zum Betreiben der Windows-Benutzeroberfläche mit Python
Erstellen von BINGO "Web Tools" mit Python (Inhaltsverzeichnis)
Ein Ei mit Python erstellen
[GUI in Python] PyQt5-Layout-Management-
So einfach wie möglich eine GUI mit Python erstellen [tkinter edition]
[GUI mit Python] PyQt5-Vorbereitung-
Asynchrone Plug-Ins mit neovim erstellen
[GUI mit Python] PyQt5 -Paint-
[GUI mit Python] PyQt5 -Widget II-
Erstellen eines bestimmten Baums mit Scikit-Learn
Lassen Sie uns eine GUI mit Python erstellen.
Erstellen eines Flask-Servers mit Docker
[GUI mit Python] PyQt5-Der erste Schritt-
Einfache GUI App mit Tkinter Text
[GUI in Python] PyQt5-Drag & Drop-
GUI-Erstellung mit Pyside2 <Kindergartenlevel>
Befehle beim Erstellen von SNS mit Django
[GUI mit Python] PyQt5 -Custom Widget-
Machen Sie Scrapy exe mit Pyinstaller
Zeichnen Sie ein Diagramm mit der PySimple-Benutzeroberfläche
[Python] Erstellen mehrerer Fenster mit Tkinter
Erstellen einer exe-Datei mit Python PyInstaller: PC friert bei paralleler Verarbeitung ein