I try to build my (fine working) python 3.6 tkinter gui app to a windows excecutable. After hours of trial an error (with some name and dll issues) I got it to run. But it seems to have varoius of bugs. Some functions seem not to work and I have no console output of the produced error... is there a way to debug the exe?
this is my setup.py
import sys
from cx_Freeze import setup, Executable
import os
os.environ['TCL_LIBRARY'] = r'C:\Users\xxx\AppData\Local\Programs\Python\Python36\tcl\tcl8.6'
os.environ['TK_LIBRARY'] = r'C:\Users\xxx\AppData\Local\Programs\Python\Python36\tcl\tk8.6'
base = None
if sys.platform == 'win32':
base = 'Win32GUI'
executables = [
Executable('myApp.py', base=base)
]
build_exe_options = {"packages": ["tkinter",
"PIL",
"savReaderWriter",
"numpy",
"scipy",
"os"],
"include_files": ["tcl86t.dll",
"tk86t.dll"]}
setup(name='myApp',
version='0.1',
description='some description',
options = {'build_exe': build_exe_options},
executables=executables
)
myApp.py
is too big to post it here. This is a snippet that only works 'unfreezed'. You need an spss.sav file like this to try this out.
from tkinter import *
from tkinter import ttk, filedialog, messagebox
from PIL import Image, ImageTk, ImageDraw
from savReaderWriter import SavReader
import numpy as np
from scipy.ndimage import gaussian_filter
import os
class MyApp:
spss_file = None
def import_spss(self, *args):
filename = filedialog.askopenfilename()
if filename:
try:
with SavReader(filename, returnHeader=True, ioUtf8=True) as reader:
spss_file = reader.all()
self.spss_file = np.array(spss_file)
except Exception as ex:
messagebox.showinfo(title="Import SPSS File",
message="Warning: wrong file format chosen! \nAccepted formats: sav")
print(ex)
return
else:
return
def main():
App = MyApp()
App.import_spss()
print("everything works fine")
main()
if you want the console window to appear, after it is frozen, just remove this code from the setup script:
if sys.platform == 'win32':
base = 'Win32GUI'
what that code does is it tells cx_Freeze to have the console window not show up, after frozen. this is only required on windows, because on other OSes,it depends on whether or not it was run from a terminal. make sure though, when you have finished debugging it, to put that code back in, or the console window will show up in your app.
by the way, one of the most annoying problems I've ever had was when making a program with tkinter and cx_Freeze. the problem was that it was starting in the wrong directory and not able to find the TK Dll. If when you run this with the console, and you see something about a file not found, chances are you are not including it or it is in the wrong directory.
have a good day!
Related
Hello noob python user here, I am trying to make an executable using cx_freeze and librosa audio library. However every time I attempt to make the executable with cx_freeze and import the librosa library, the executable does not work. Could I have some help with this?
Note: Main code is just an example script to debugg error.
Here is main code which is example code but importing librosa. I am using this code to just
debug and it outputs the same error.
import PySimpleGUI as sg
import librosa
import IPython as ipd
sg.theme('DarkAmber') # Add a little color to your windows
# All the stuff inside your window. This is the PSG magic code compactor...
layout = [ [sg.Text('Some text on Row 1')],
[sg.Text('Enter something on Row 2'), sg.InputText()],
[sg.OK(), sg.Cancel()]]
# Create the Window
window = sg.Window('Window Title', layout)
# Event Loop to process "events"
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Cancel'):
break
window.close()
Here is my setup file for cx_Freeze
import sys
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = {"packages": ["os"], "excludes": [] }
# GUI applications require a different base on Windows (the default is for
# a console application).
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup( name = "Billy_Boy",
version = "01",
description = "My GUI application!",
options = {"build_exe": build_exe_options},
executables = [Executable("NACD_Work.py", base=base)])
Error Image cx_Freeze:
cx_Freeze error jpeg
Error Image pyinstaller
I managed to get a functional executable with pyinstaller, but it took some doing. For whatever reason, pyinstaller just feels like completely ignoring the existence of librosa, even when specified with hidden-import, so I wrote a custom hook:
import os.path
import glob
from PyInstaller.compat import EXTENSION_SUFFIXES
from PyInstaller.utils.hooks import collect_data_files, get_module_file_attribute
datas = collect_data_files('librosa')
librosa_dir = os.path.dirname(get_module_file_attribute('librosa'))
for ext in EXTENSION_SUFFIXES:
ffimods = glob.glob(os.path.join(librosa_dir, '_lib', f'*_cffi_*{ext}*'))
dest_dir = os.path.join('librosa', '_lib')
for f in ffimods:
binaries.append((f, dest_dir))
Even with this, I still had a missing import, but that one worked as a hidden import. So overall I got the code
import PySimpleGUI as sg
import librosa
import numpy as np
import sys
def main(args):
test_data = np.zeros(10000)
test_data[::50] = 1
print(librosa.beat.tempo(test_data))
sg.theme('DarkAmber') # Add a little color to your windows
# All the stuff inside your window. This is the PSG magic code compactor...
layout = [ [sg.Text('Some text on Row 1')],
[sg.Text('Enter something on Row 2'), sg.InputText()],
[sg.OK(), sg.Cancel()]]
# Create the Window
window = sg.Window('Window Title', layout)
# Event Loop to process "events"
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Cancel'):
break
window.close()
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))
to build into a functional executable with the command
pyinstaller -F --hidden-import librosa --additional-hooks-dir . --hidden-import sklearn.utils._weight_vector .\test.py
import sys
from cx_Freeze import setup, Executable
build_exe_options = {'packages': ['os','tkinter','random',
'heapq','collections','sys','pickle']}
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup( name = 'Game',
version = '0.02',
description = 'My GUI application!',
options = {'build_exe': build_exe_options},
executables = [Executable('Game.py', base=base)])
here's the code of the setup
from tkinter import *
value_a = 'hahaha'
a =messagebox.showinfo('laugh',value_a)
and the code that would executed
the erorr is Nameerorr : name "messagebox" is not defined when I typed python 123.py build or python haha.py build in cmd
I already used import *, if I run the code it shows message but neither in cmd nor .exe
Should I use import tkinter as tk? But it is difficult to read my code by adding "tk", I want to keep import * so that no "tk.xxx" is needed and it will still works on exe.
from tkinter import * does not work for messagebox, so you must import the message box individually like below
from tkinter import messagebox
I had this problem too. It worked OK in the IDE but not in direct run mode.
Adding import tkinter.messagebox as messagebox fixed the problem.
Thanks, G.
I am new to cx_Freeze.
I started using it in a big python application. That application is using PySide and uses multiprocessing. On application start and each time a thread starts I see a cmd window flashing shortly (just open and close really quick.. no time to read anything).
Now I tried with a very simple application. Like this:
import os
import sys
import multiprocessing
from PySide import QtGui
from PySide import QtCore
from PySide import QtNetwork
if __name__ == '__main__':
# multiprocessing support
multiprocessing.freeze_support()
# init application
app = QtGui.QApplication.instance()
if not app:
app = QtGui.QApplication(sys.argv)
QtGui.QApplication.setQuitOnLastWindowClosed(False)
# check systemtray
if not QtGui.QSystemTrayIcon.isSystemTrayAvailable():
QtGui.QMessageBox.critical(None, "Systray", "I couldn't detect any system tray on this system.")
sys.exit(1) # quick kill
wid = QtGui.QWidget()
wid.resize(250, 150)
wid.setWindowTitle('Simple')
wid.show()
sys.exit(app.exec_())
But this is still showing and flashing a window on start.
Here is the setup file I use with this:
from cx_Freeze import setup, Executable
# dependencies
build_exe_options = {
"packages": [#"os", "sys", "glob", "re", "atexit",
"PySide.QtCore", "PySide.QtGui", "PySide.QtXml", 'PySide.QtXml',
'xml', 'P4', 'MYRefs_module', 'MYUtils_module', 'logging',
'multiprocessing'],
# "include_files": mfiles, # this isn't necessary after all
"excludes": ["Tkinter", "Tkconstants", "tcl"],
"build_exe": "build",
"icon": "img/icon.ico",
"include_msvcr":True
}
executable = [
Executable("main.pyw",
base="Win32GUI",
initScript = None,
targetName="Example.exe",
targetDir="build",
copyDependentFiles=True,
)
]
setup(
name="Example",
version="0.1",
description="Example", # Using the word "test" makes the exe to invoke the UAC in win7. WTH?
author="Me",
options={"build_exe": build_exe_options},
executables=executable,
requires=['PySide', 'cx_Freeze', 'P4', 'xml']
)
May be I am doing something wrong? Is the multiprocessing support the issue? Any hint appreciated.
Btw, I am using python 2.7.3x64 and cx_Freeze 4.3.4, PySide 1.2.2 ...
solved.
And after finding the problem, the question was probably not right.
I catch a os.system('rd /s /q somefolder') call. In one of my modules loaded.
As soon as I remove that, which is not necessary right now, the console window flashes dont show again.
I used it in one single place, but the flashes appeared in several places (threads). I used as well Popen, which apparently works fine.
I have freezed a Tkinter-using GUI Python 3.4 app with cx_Freeze and when I tried to run it, I was presented the following error:
NameError: name 'font' is not defined.
When I remove all references to font from my code (i. e., if I don't set ttk Label fonts anywhere In the code), it works just fine and the exe runs nicely. I have checked the library.zip archive created by the freeze script and it does contain the font.pyc file in the tkinter directory.
This is what my setup.py file looks like:
import cx_Freeze
import sys
import tkinter
base = None
if sys.platform == 'win32':
base = "Win32GUI"
executables = [cx_Freeze.Executable("rocnikovka.py", base=base)]
cx_Freeze.setup(
name = "Number evolution",
options = {"build_exe": {"packages":["tkinter", "tkinter.font"], "includes": ["tkinter", "tkinter.font"]}},
version = "0.01",
description = "Rocnikovka",
executables = executables
)
Any help is appreciated.
UPDATE: I have also tried making an executable out of the script with py2exe but ended up with the same result. Seems like a problem with tkinter rather than with cx_Freeze.
UPDATE #2: I import tkinter and ttk in the script like this:
from tkinter import *
from tkinter import ttk
I have a few fonts defined in the script, like this one:
font_title = font.Font(family = "Exo 2", size = 20, weight = "bold")
which I then use as the font parameter of ttk.Label objects.
This all works just fine when run as a script in IDLE.
Thanks to Arden, I was able to get it to work adding an explicit font sub-module import:
from tkinter import font
Works perfectly good now.
I've got a problem.
I've got a program // script, which works perfectly, but when I compile it using cx_Freeze, it doesn't work: Name "filedialog" is not defined.
Do I have to import it on another way??
My Script part:
from tkinter import *
from shutil import *
import sys
import os
#Vars:
location = os.path.dirname(sys.argv[0])+"/"
if os.path.isfile(location+"filedic.txt"):
file = open(location+"filedic.txt","r").read()
else:
fiRoot = Tk()
fiRoot.withdraw()
file = str(filedialog.askdirectory())
And my setup script:
import sys
from cx_Freeze import setup, Executable
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup(
name = "BlackChat",
version = "1.3",
description = "BlackChat was programmed by David Jandrey",
executables = [Executable("BlackChat.py", base = base,icon = "BlackChat.ico")])
Thanks for coming answers.
Reposting as an answer:
Doing from tkinter import filedialog explicitly might make it work - it looks like cx_Freeze isn't copying the filedialog module.