hello
I try to learn Python ...
I did by myself a little software for read data from XLSX, every things runs good when I launch by the "normal way / python way " (ctrl + B in sublime text).
... BUT ...
When I compil it to get my ".exe" with "cx.freeze" and when launch my .exe, I get this error window :
(https://i.stack.imgur.com/E2GVw.png)
I tryed with the library asked I updated all my library but nothing
here the begin and the end of my code with the library installed by PIP:
# c-*- coding: utf-8 -*-
# Bibliotheques
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import openpyxl
import xlrd
import mpl_toolkits
import sys
import os
from tkinter import *
from tkinter import messagebox
from tkinter.filedialog import * # askopenfilename
from functools import partial
from PIL import Image, ImageTk
class MyApp(Tk): # --- Class.N°1 --- #
def __init__(self):
Tk.__init__(self)
if __name__ == '__main__':
MyApp()
here the CX.freeze scrypt I used :
from cx_Freeze import setup, Executable
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')
base = "Win32GUI" #pour appli graphique ss windows
#base = "console" #pour appli console
options = {
'build_exe': {
'include_files':[
os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'),
os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'),
],
},
}
# On appelle la fonction setup
setup(name = "GraphEditor",
options = options,
version = "V1.1.2",
author = "Scorn",
description = "Reading and editing trends from 2D table",
executables = [Executable("GraphEditor.py",base=base, icon="xln.ico")]
)
So my question is : why I have this error, and how I can solve it ?
thx you for your time and your answer :)
I found that CXFreeze had not worked well in many cases. So I prefer to use Nuitka as an alternative. It's quite straightforward to use.
nuitka --file-reference-choice=runtime --recurse-to=[some_module] main.py
I used Nuitka to freeze a very big Python app (integrated web server using NumPy and OpenGL). Some reports say there's some problem when compiling NumPy. But I think Pandas will be fine with it.
I solved my problem.
I used the very very good: Auto PY to EXE https://pypi.org/project/auto-py-to-exe/ .
I downgrade my Python to V 3.7
Take care to clean your library because for example: I had 2 times Tkinter, downloaded one time by PIP and already inside the standard library.
Related
I'm having a python project and use git as version control software.
The software will be deployed using Cx_Freeze.
I would like to display the version and author (and possibly other metadata) captured during the build process (freezing the script) within an About dialogue in my Application.
This is an example of the setup script:
import sys
import subprocess
from cx_Freeze import setup, Executable
build_exe_options = {}
base = "Win32GUI"
version = subprocess.run(['git', 'describe', '--abbrev=4', '--dirty', '--always', '--tags'],
capture_output=True, encoding='utf-8').stdout.strip()
setup(
name="XY",
version=version,
author="My Name",
description="Mysterious GUI application",
options={"build_exe": build_exe_options},
executables=[Executable("XY.py", base=base)],
)
Simple example of an About dialogue:
from tkinter import messagebox
def on_about():
messagebox.showinfo(f'About', 'Software XY, written by {author}, version {version}')
# Should display e.g. 'Software XY, written by My Name, version 4b06-dirty'
Does anyone know if this is possible and how to achieve this?
Thanks to all in advance!
I came up with a first solution where I create a sub-module within the main package of my application when the setup script is being executed. I import the __version__ variable into the __init__.py of that package only when its frozen and if the sub-module exists:
setup.py:
import subprocess
import os.path
import mymodule
from cx_Freeze import setup, Executable
def create_versionmodule(packagepath: str):
"""
creates a file packagepath/_version.py which defines a __version__ variable
which contains the stripped output of "git describe --dirty --always --tags"
"""
version = subprocess.run(['git', 'describe', '--dirty', '--always', '--tags'],
capture_output=True, encoding='utf-8').stdout.strip()
with open(os.path.join(packagepath, '_version.py'), mode='w', encoding='utf-8') as file:
file.write(f'__version__: str = {version!r}\n')
build_exe_options = {}
base = "Win32GUI"
create_versionmodule(packagepath=os.path.dirname(mymodule.__file__))
setup(
name="XY",
description="Mysterious GUI application",
options={"build_exe": build_exe_options},
executables=[Executable("XY.py", base=base)],
)
mymodule/__init__.py:
import sys as _sys
__version__ = 'UNKNOWN'
if getattr(_sys, "frozen", False):
try:
from mymodule._version import __version__
except ModuleNotFoundError:
pass
Now I can access the version variable from everywhere in my code:
import mymodule
from tkinter import messagebox
def on_about():
messagebox.showinfo(f'About', 'Software XY, version {mymodule.__version__}')
I have a code in python and I used cx_Freeze to convert it to an .exe. This task works without any error.
But when I try to run my .exe the following error happens:
from tensorflow.python import tf2
ImportError: cannot import name 'tf2'
My ann.py code is:
import numpy as np
import sys
.
.
.
X_test=XinN
Y_test=XoutN
#Criando o modelo
from keras.models import Sequential
from keras.layers import Dense
modelo = Sequential()
for i in range(int((num_par-4)/2)):
modelo.add(Dense(int(parametros[i+4]), kernel_initializer='normal',activation=ativacao(int(parametros[i+5])))) #camadas ocultas
modelo.add(Dense(num_out, kernel_initializer='normal',activation=ativacao(int(parametros[num_par-1])))) #camada de saída
modelo.compile(optimizer='adam',loss='mean_squared_error')
hist = modelo.fit(X_train, Y_train, epochs=800, verbose=0, batch_size=10,validation_data=(X_test, Y_test))
XobsoutN=modelo.predict(XobsN)
Xobsout=XobsoutN*(max_out-min_out)+min_out
np.savetxt("Xobsout.txt",Xobsout.transpose(),delimiter='\t')
loss=[" "," "]
loss[0] = hist.history['loss']
loss[1] = hist.history['val_loss']
np.savetxt("erro.txt",loss,delimiter='\t')
And my setyp.py for cx_Freeze is:
from cx_Freeze import setup, Executable
import sys
base = None
if sys.platform == 'win32':
base = None
executables = [Executable("ANN.py", base=base)]
packages = ["idna"]
options = {
'build_exe': {
'includes':['atexit', 'numpy.core._methods', 'numpy.lib.format'],
'packages':packages,
},
}
import os
os.environ['TCL_LIBRARY'] = "C:\\ProgramData\\Anaconda3\\tcl\\tcl8.6"
os.environ['TK_LIBRARY'] = "C:\\ProgramData\\Anaconda3\\tcl\\tk8.6"
setup(
name = "Nome Executavel",
options = options,
version = "1.0",
description = 'Descricao do seu arquivo',
executables = executables
)
Anyone can help me to solve this error?
I had many others errors using cx_Freeze and this forum was pretty helpful to solve all of them. Thanks a lot!
Try to add "tensorflow" to the packages list in your setup.py script:
packages = ["idna", "tensorflow"]
I created a small converter and after building it with CX_Freeze it shows this error
Traceback (most recent call last):
File "C:\users\LDC\AppData\Local\Programs\python\python36-32\lib\sitr\e-packages\cx_freeze\initscripts_startup_.py", line14 in run module.run()
File "C:\users\LDC\AppData\Local\Programs\python\python36-32\lib\sitr\e-packages\cx_freeze\initscripts\console.py", line26 in run exec(code,m.dict)
File"GUI1.py",line 1, in
File
"C:\USERS\LDC\APPDATA\LOCAL\PROGRAMS\PYTHON\PYTHON36-32\LIB\TKINTER_INIT_.PY",line36,in
import_tkinter#If this fails your python may not be configured for Tk
ImportError: DLL load failed: the specified module could not be found
This is a screen shot from the error
Now this is my code:
from tkinter import *
window1=Tk()
def convert():
var2=var1.get()
var3=var2*3.785
e2.insert(0,var3)
def clear():
e1.delete(0,END)
e2.delete(0,END)
def quit():
window1.destroy()
var1=IntVar()
label1=Label(window1,text='Gallons',padx=25).grid(row=0,sticky=W)
e1=Entry(window1,width=25,textvariable=var1)
e1.grid(row=0,column=1)
label2=Label(window1,text='Liters',padx=25).grid(row=1,sticky=W)
e2=Entry(window1,width=25)
e2.grid(row=1,column=1)
window1.title("Converter")
window1.geometry("400x200+200+200")
button1= Button(text='convert',command=convert,width=15,).grid(row=4,column=0)
button2= Button(text='clear',command=clear,width=15).grid(row=4,column=1)
button3= Button(text='exit',command=quit,width=15).grid(row=5,column=1)
mymenu=Menu()
mymenu.add_cascade(label='File')
mymenu.add_cascade(label='Edit')
mymenu.add_cascade(label='View')
mymenu.add_cascade(label='Tools')
mymenu.add_cascade(label='Help')
window1.config(menu=mymenu)
window1.mainloop()
and this is the setup code
import cx_Freeze
import sys
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')
base = None
if sys.platform == 'win32':
base = "Win32GUI"
executables = [cx_Freeze.Executable("GUI1.py", base=base, icon="clienticon.ico")]
cx_Freeze.setup(
name = "GUI1",
options = {"build_exe": {"packages":["tkinter"], "include_files":["clienticon.ico"]}},
version = "0.01",
description = "Ya Rb",
executables = executables
)
I tried the following with no luck:
1. uninstalled cx freeze and installed it again
2. tried different version of python .. python 2.7
3. tried to use py2exe and pyinstaller got different errors
4. also made sure that the python path in the environment is set correctly
Thanks in advance appreciate your help..
This error is not as bad as it looks. You just need to know the path to your Python installation.
What the error means: you've included the tkinter library but forgotten the tkinter run-times (tk86t.dll and tcl86t.dll). For your script to work you need to include them.
This can be done with the use of include_files statement. A quick search through the installation reveals they are located in a folder called DLLs. We need to give the file path and the file names we want to the setup script. This can be done like this:
"include_files":["<path to python>/Python36-32/DLLs/tcl86t.dll","<path to python>/Python36-32/DLLs/tk86t.dll"]
and it will now work.
Your setup script will look like this:
import cx_Freeze
import sys
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')
base = None
if sys.platform == 'win32':
base = "Win32GUI"
executables = [cx_Freeze.Executable("GUI1.py", base=base, icon="clienticon.ico")]
cx_Freeze.setup(
name = "GUI1",
options = {"build_exe": {"packages":["tkinter"], "include_files":["clienticon.ico", "<path to python>/Python36-32/DLLs/tcl86t.dll","<path to python>/Python36-32/DLLs/tk86t.dll"]}},
version = "0.01",
description = "Ya Rb",
executables = executables
)
My program is working in anaconda spyder. however, after freezing it all widgets that use the tkinter module work except for the widget with xgboost and pandas. No error showed, the build worked but the button is not working and not showing the widget.
I've tried importing and including xgboost in my setup.py file but all other widgets with tkinter didn't work altogether. No error still though. have anyone experienced or solved this issue?
Here's the closest thing that worked. This is my setup.py, when the other widgets worked with tkinter but not the one with xgboost and pandas.
from cx_Freeze import setup, Executable
import sys
import os
includes = []
include_files = [r"C:/Users/USER/Anaconda3/DLLs/tcl86t.dll",
r"C:/Users/USER/Anaconda3/DLLs/tk86t.dll",
r"C:/Users/USER/SAMPLE/xgboost_USE.model",
r"C:/Users/USER/SAMPLE/P1.ico"]
os.environ['TCL_LIBRARY'] = "C:/Users/USER/Anaconda3/tcl/tcl8.6"
os.environ['TK_LIBRARY'] = "C:/Users/USER/Anaconda3/tcl/tk8.6"
base = 'Win32GUI' if sys.platform == 'win32' else None
setup(name=application_title, version='1.0', description='SAMPLE',
options={"build_exe": {"includes": includes, "include_files":
include_files}},executables=
[Executable(r'C:/Users/USER/SAMPLE/sample.py', base=base)])
Please help.
I dont have any experience with xgboost but I know when you cx freeze pandas you will need to explicitly include numpy. I'll share a setup file I have that has pandas (and some other things you can delete out like boto I assume)
import sys
import cx_Freeze
import os.path
import scipy
base = None
if sys.platform == 'win32':
base = "Win32GUI"
#This part may depend on where your installation is
#This part is essential to copy the tkinter DLL files over
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')
os.environ['REQUESTS_CA_BUNDLE'] = r'C:\ProgramData\Anaconda3\Lib\site-packages\botocore\vendored\requests\cacert.pem'
executables = [cx_Freeze.Executable("test.py", base=base)]
addtional_mods = ['numpy.core._methods', 'numpy.lib.format']
packages = ["idna", "numpy", "boto3", 'boto3.s3.transfer', 'boto3.s3.inject', 'multiprocessing', "xlwt", 'numpy.core._methods', 'pandas']
options = {
'build_exe': {
'include_files':[
os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'),
os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'),
os.path.dirname(scipy.__file__),
r'C:\ProgramData\Anaconda3\Lib\site-packages\botocore\vendored\requests\cacert.pem',
r'C:\ProgramData\Anaconda3\Lib\site-packages\botocore',
],
'includes': addtional_mods,
'packages':packages,
},
}
cx_Freeze.setup(
name = "Test",
options = options,
version = "1.0.0.0",
description = 'Test',
executables = executables
)
I'm trying to make an exe by py2exe. The program is showing a popup-like window using Tkinter. The problem is, everything works fine when I run the setup like this:
setup(windows = [{'script': "msg.py"}], zipfile = None)
but it fails when I try to make an one-file exe:
setup(windows = [{'script': "msg.py"}], zipfile = None, options = {'py2exe': {'bundle_files': 1, 'compressed': True}})
Actually the final exe runs without problems, but it doesn't display any window. I've read there may be problems with bundle_files=1 at Windows 7, but I also tried bundle_files=2 with the same effect.
Here is my msg.py script:
from win32gui import FindWindow, SetForegroundWindow
from Image import open as iopen
from ImageTk import PhotoImage
from Tkinter import Tk, Label
from threading import Timer
from subprocess import Popen
import os
def Thread(t, fun, arg=None):
if arg<>None: x = Timer(t, fun, arg)
else: x = Timer(t, fun)
x.daemon = True
x.start()
def NewMessage():
global root
if not os.path.exists('dane/MSG'):
open('dane/MSG', 'w').write('')
root = Tk()
img = PhotoImage(iopen("incl/nowa.png"))
label = Label(root, image=img)
label.image = img
label.bind("<Button-1>", Click)
label.pack()
root.geometry('-0-40')
root.wm_attributes("-topmost", 1)
root.overrideredirect(1)
root.mainloop()
def Click(event):
global root, exit
root.destroy()
os.remove('dane/MSG')
OpenApp()
exit = True
def OpenApp():
hwnd = FindWindow(None, 'My program name')
if hwnd: SetForegroundWindow(hwnd)
else: Popen('app.exe')
root, exit = None, False
NewMessage()
Any ideas? I've read there are some problems with Tkinter, but there were about compilation. My script is compiled and it doesn't throw any exceptions, but doesn't show the window...
I ended up encountering this same issue, my solution involved doing the following:
Add
"dll_excludes": ["tcl85.dll", "tk85.dll"],
in your options = {...}
and then manually copy those two DLLs from
PYTHON_PATH\DLLs\ (in my case C:\Python27\DLLs)
to the location of your exe and try running it.
An alternative to dll_excludes and manual copying is to patch py2exe to know these files have to be placed directly in the dist directory.
Inside build_exe.py, there's a class called py2exe, which contains a list dlls_in_exedir for dll that have to go there. This list is set during a function named plat_prepare, and you can add the tclXX.dll and tkXX.dll files to it to make sure they are copied correctly.
Of course, unless you're the only one who will ever build this, you don't necessarily know which Tcl and Tk version you need to bundle - someone might have built their Python themselves, or are using an older Python with older DLLs. Therefore, you'll need to check which versions the system is actually using. py2exe actually already does this in a different place: by importing the internal _tkinter module (the actual Tk interface, usually a DLL) and accessing TK_VERSION and TCL_VERSION, which you can then use to generate and add the correct filenames.
If others are supposed to build your application, you probably don't want to make them modify their py2exe install, so here's how you can monkeypatch it from your setup.py:
import py2exe
py2exe.build_exe.py2exe.old_prepare = py2exe.build_exe.py2exe.plat_prepare
def new_prep(self):
self.old_prepare()
from _tkinter import TK_VERSION, TCL_VERSION
self.dlls_in_exedir.append('tcl{0}.dll'.format(TCL_VERSION.replace('.','')))
self.dlls_in_exedir.append('tk{0}.dll'.format(TK_VERSION.replace('.','')))
py2exe.build_exe.py2exe.plat_prepare = new_prep
This even works with bundle_files=1 on Windows 7.
If you have only one version the you can copy files with
via data_file. Below a full example:
WinXP
Python2.7.6
tk8.5
tcl8.5
tix8.4.3
py2exe 0.6.9
foo.py:
# -*- coding: iso-8859-1 -*-
import Tkinter
"""
sets TCL_LIBRARY, TIX_LIBRARY and TK_LIBRARY - see installation Lib\lib-tk\FixTk.py
"""
Tkinter._test()
Setup.py :
# -*- coding: iso-8859-1 -*-
from distutils.core import setup
import py2exe
import sys
import os
import os.path
sys.argv.append ('py2exe')
setup (
options =
{'py2exe':
{ "bundle_files" : 1 # 3 = don't bundle (default)
# 2 = bundle everything but the Python interpreter
# 1 = bundle everything, including the Python interpreter
, "compressed" : False # (boolean) create a compressed zipfile
, "unbuffered" : False # if true, use unbuffered binary stdout and stderr
, "includes" :
[ "Tkinter", "Tkconstants"
]
, "excludes" : ["tcl", ]
, "optimize" : 0 #-O
, "packages" :
[
]
, "dist_dir" : "foo"
, "dll_excludes": ["tcl85.dll", "tk85.dll"]
,
}
}
, windows =
["foo.py"
]
, zipfile = None
# the syntax for data files is a list of tuples with (dest_dir, [sourcefiles])
# if only [sourcefiles] then they are copied to dist_dir
, data_files = [ os.path.join (sys.prefix, "DLLs", f)
for f in os.listdir (os.path.join (sys.prefix, "DLLs"))
if ( f.lower ().startswith (("tcl", "tk"))
and f.lower ().endswith ((".dll", ))
)
]
,
)