首页 > 解决方案 > tkinter doesn't work after building the app with cx_Freeze on python

问题描述

I'm trying to create an executable app with a user interface using tkinter and cx_freeze the tkinter app works perfectly before I'm packing it into an executable.

But once I'm building the app with cx_freeze I'm meeting an issue when I ask the app to show the dialog box and return the path it seems like it's actually processing what's defined before the path = fd.askdirectory() but not this line and after, see the definition bellow:

def run_and_close():
    file_name_clean, file_name_dirty, col_pos_clean, col_pos_dirty=file_names()
    connection, cursor = createDBconnection('fuzzy_matching')

    from to_sql_fuzzy import to_sql_fuzzy
    col_clean, col_dirty = to_sql_fuzzy(file_name_clean,col_pos_clean,file_name_dirty,col_pos_dirty,connection,cursor)
    print(col_clean, col_dirty)

    import cosine_fuzzy_tkinter
    matches_df = cosine_fuzzy_tkinter.run_cosine_match(col_clean,col_dirty,connection,cursor)

    path = fd.askdirectory() # shows dialog box and return the path
    matches_df.to_excel(f'{path}/output_fuzzy_{col_clean}_{col_dirty}.xlsx')
    messagebox.showinfo("Saved!", f"Excel file saved on {path}")

here's the whole tkinter code

try:
    import tkinter as tk
    from tkinter import *
    from tkinter import messagebox
    from tkinter import filedialog as fd
except:
    import Tkinter as tk
    from Tkinter import *
    from Tkinter import messagebox
    from Tkinter import filedialog as fd

import pandas as pd
import sqlite3 as sql

def createDBconnection(DBname):
    db_to= f'{DBname}.db'
    connection = sql.connect(db_to)
    cursor = connection.cursor()
    return connection, cursor

def get_file_name(file_entry):
    file_name = fd.askopenfilename(initialdir = "/",title = "Select file", filetypes = (("excel files","*.xls*"),))
    file_entry.delete(0,END)
    file_entry.insert(0,file_name)

def file_names():
    file_name_clean=entry_xl_clean.get()
    file_name_dirty=entry_xl_dirty.get()
    col_pos_clean=entry_col_clean.get()
    col_pos_dirty=entry_col_dirty.get()
    return file_name_clean, file_name_dirty, col_pos_clean, col_pos_dirty

def run_and_close():
    file_name_clean, file_name_dirty, col_pos_clean, col_pos_dirty=file_names()
    connection, cursor = createDBconnection('fuzzy_matching')
    
    from to_sql_fuzzy import to_sql_fuzzy
    col_clean, col_dirty = to_sql_fuzzy(file_name_clean,col_pos_clean,file_name_dirty,col_pos_dirty,connection,cursor)
    print(col_clean, col_dirty)

    import cosine_fuzzy_tkinter
    matches_df = cosine_fuzzy_tkinter.run_cosine_match(col_clean,col_dirty,connection,cursor)

    path = fd.askdirectory() # shows dialog box and return the path
    matches_df.to_excel(f'{path}/output_fuzzy_{col_clean}_{col_dirty}.xlsx')
    messagebox.showinfo("Saved!", f"Excel file saved on {path}")

def close(event=None):
    fenetre.withdraw() # if you want to bring it back
    sys.exit() # if you want to exit the entire thing
 
fenetre = tk.Tk()
fenetre.title("FUZZY MATCHING")
fenetre.iconbitmap(r"S:\99Contractors\Python\Fuzzy\apps\fuzzy.ico")

label_xl_clean = tk.Label(fenetre, text="Input XL clean")
label_xl_clean.grid(row=0, column=0 ,sticky=W)
entry_xl_clean=tk.Entry(fenetre, text="", width=50)
entry_xl_clean.grid(row=0, column=1, sticky=W, padx=5)
entry_col_clean=tk.Entry(fenetre, text="", width=10)
entry_col_clean.grid(row=0, column=3, sticky=W, padx=5)
entry_col_clean.insert(0, 1)
button_browse_clean = tk.Button(fenetre, text="Browse...", width=10, command=lambda:get_file_name(entry_xl_clean))
button_browse_clean.grid(row=0, column=4, sticky=W)

label_xl_dirty = tk.Label(fenetre, text="Input XL dirty")
label_xl_dirty.grid(row=1, column=0 ,sticky=W)
entry_xl_dirty=tk.Entry(fenetre, text="", width=50)
entry_xl_dirty.grid(row=1, column=1, sticky=W, padx=5)
entry_col_dirty=tk.Entry(fenetre, text="", width=10)
entry_col_dirty.grid(row=1, column=3, sticky=W, padx=5)
entry_col_dirty.insert(0, 1)
button_browse_dirty = tk.Button(fenetre, text="Browse...", width=10, command=lambda:get_file_name(entry_xl_dirty))
button_browse_dirty.grid(row=1, column=4, sticky=W)

button_ok = tk.Button(fenetre, text="Ok",     command=lambda:run_and_close(), width=10)
button_ok.grid(row=3, column=3, sticky=E, padx=5)
button_close = tk.Button(fenetre, text="Cancel", command=close, width=10)
button_close.grid(row=3, column=4, sticky=W)

fenetre.bind('<Return>', run_and_close)
fenetre.bind('<Escape>', close)
fenetre.mainloop()

here's the setup.py file

import os.path

PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')

packages = ["tkinter", 'tkfilebrowser']

include_files = [os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'),
         os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'),
         'C:/Users/user/Documents/Fuzzy/apps - Copy/cosine_fuzzy_tkinter.py',
         'C:/Users/user/Documents/Fuzzy/apps - Copy/to_sql_fuzzy.py',
         'C:/Users/user/Documents/Fuzzy/apps - Copy/fuzzy.ico']

setup(
    name='FUZZYAPP',
    description='Perform fuzzy match between 2 excel files',
    version='0.1',
    options={'build_exe': {'include_files': include_files}},
    executables=[Executable('tkinter_test_2.py', 
                targetName='fuzzyapp.exe', 
                icon='C:/Users/djemen01/Documents/Fuzzy/apps/fuzzy.ico', 
                copyright='Copyright (C) <name> 2020', 
                base='Win32GUI')]
)

标签: pythonpython-3.xtkinterexecx-freeze

解决方案


推荐阅读