Python program fails after build with cx_Freeze in Windows - python

I have a Windows desktop Python 3.9 program using wx and ObjectListView for user forms interaction.
When I run the program inside VSCode all is working fine.
Running the exe after building with cx_Freeze, the program fails on this line:
for attr in self.record.__table__.columns._data.keys():
This is the Class up to this line:
class AddModForm(wx.Dialog):
"""
Opens a single-record form for add/update of record.
dict is a dictionary of the object to work on (defined in globalvariables.py).
"""
def __init__(self, targetObject, olv_dict, row=None, titlePrefix="Add", titleLabel="Record", addRecord=True):
"""Constructor"""
wx.Dialog.__init__(self, None, title="{} {}".format(titlePrefix, titleLabel))
self.targetObject = targetObject
self.olv_dict = olv_dict
self.addRecord = addRecord
self.selectedRow = row
lblSize = (80,-1)
txtSize40 = (40, -1)
txtSize60 = (60, -1)
txtSize80 = (80, -1)
recordToUpdate = {}
if self.selectedRow: # if updating - fetch record
self.recordId = self.selectedRow.id
self.record = forms_controller.getRecordByKey(targetObject, {"id": self.recordId})
# arrange record attributes in a dictionary:
for attr in self.record.__table__.columns._data.keys():
recordToUpdate.update({attr: getattr(self.record, attr)})
Up to this line, the program runs OK, including opening and interacting through user forms, database interaction etc.
This Class is called following a button click by the user, called in this line (in another Class):
self.modifyForm = form_addmod.AddModForm(Departments, globalvariables.dict_olv_departments, selectedRow, "Update", "Department", False)
As far as the user experience, the button is clicked but the called form just won't open. No error is shown.
For reference, this is the setup.py for the build:
import sys
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = {"packages": ["configparser", "pymysql", "sqlalchemy", "ObjectListView", "validate_email", "wx"],
"include-files": ["etc\configuration.txt", "backup_db"]}
# GUI applications require a different base on Windows (the default is for a
# console application).
base = None
if sys.platform == "win32":
base = "Win32GUI"
includefiles = ['etc\\']
includes = []
excludes = ['Tkinter']
packages = ["configparser", "pymysql", "sqlalchemy", "ObjectListView", "validate_email", "wx"]
setup(
name = 'Employees Management',
version = '1.0',
description = '...',
author = '...',
author_email = 'info#...',
options = {'build_exe': {'includes':includes,'excludes':excludes,'packages':packages,'include_files':includefiles}},
executables = [Executable(script="main.py", base=base, icon="media\LAVI.ico", targetName="Employees Management.exe")]
)
This program used to work perfect on Python 3.6.5. I just needed a small fix, and re-installing some libraries again (probably for versions compatibility).
Any idea where can I look for? any known issues with cx_Freeze build process or runtime on Windows with this statement? maybe referencing the Table object?

Related

Python Orange (Version 3.3.6) on Window 10 can't create demo widget

As per the documentation, I created the following files:
setup.py (in folder C:\Python34\Lib\site-packages\Orange\widgets\orange-demo)
from setuptools import setup
setup(name="Demo",
packages=["orangedemo"],
package_data={"orangedemo": ["icons/*.svg"]},
classifiers=["Example :: Invalid"],
# Declare orangedemo package to contain widgets for the "Demo" category
entry_points={"orange.widgets": "Demo = orangedemo"},
)
and OWDataSamplerA.py (in folder C:\Python34\Lib\site-packages\Orange\widgets\orange-demo\orangedemo)
import sys
import numpy
import Orange.data
from Orange.widgets import widget, gui
class OWDataSamplerA (widget.OWWidget):
name = "Data Sampler"
description = "Randomly selects a subset of instances from the data set"
icon = "icons/DataSamplerA.svg"
priority = 10
inputs = [("Data", Orange.data.Table, "set_data")]
outputs = [("Sampled Data", Orange.data.Table)]
want_main_area = False
def __init__(self):
super().__init__()
# GUI
box = gui.widgetBox(self.controlArea, "Info")
self.infoa = gui.widgetLabel(box, 'No data on input yet, waiting to get something.')
self.infob = gui.widgetLabel(box, '')
def set_data(self, dataset):
if dataset is not None:
self.infoa.setText('%d instances in input data set' % len(dataset))
indices = numpy.random.permutation(len(dataset))
indices = indices[:int(numpy.ceil(len(dataset) * 0.1))]
sample = dataset[indices]
self.infob.setText('%d sampled instances' % len(sample))
self.send("Sampled Data", sample)
else:
self.infoa.setText('No data on input yet, waiting to get something.')
self.infob.setText('')
self.send("Sampled Data", None)
I created a .svg icon and left the __init__.py file blank. After running pip install -e ., a Demo.egg-info directory is created and it includes several files, but no demo widget is created. After restarting Python Orange no visible changes occur at all.
Any advice would be most welcome.
A separate version of Python 3.6 is bundled with Orange.
To install a new widget, you need to have the proper Python instance in the path.
On Windows, you can find a special shortcut "Orange Command Prompt". You will need to run it as Administrator to install new packages in newer version.
Once in the appropriate directory, you can run your pip install.. command.

Cx_freeze exe failing to completely import docx

I have a pretty hefty python script that I'm trying to cx_freeze, however when I run the executable file I keep getting the same error and it appears to be related to the docx module.
I'm using Python 3.3.5 with docx 0.7.6-py33 on a Windows 8.1 machine.
This is my setup script.
from cx_Freeze import setup, Executable
includefiles = ['logo.ico','db.db','dbloc.bin']
includes = []
excludes = []
packages = ['tkinter','docx','sys', 'sqlite3', 'os', 'hashlib', 'random', 'uuid', 'base64', 'tempfile', 'win32api',
'winreg', 'ntplib', 'winsound', 'time', 'csv', 'webbrowser', 'inspect','datetime', 'decimal', 'ctypes',
'win32com.client','operator']
exe = Executable(
# what to build
script = "NEPOS.py",
initScript = None,
base = 'Win32GUI',
targetName = "Nepos.exe",
copyDependentFiles = True,
compress = True,
appendScriptToExe = True,
appendScriptToLibrary = True,
icon = 'Icon.ico'
)
setup(
name = "MyProgram",
version = "1.0.0",
description = 'Description',
author = "Joe Bloggs",
author_email = "123#gmail.com",
options = {"build_exe": {"excludes":excludes,"packages":packages,
"include_files":includefiles}},
executables = [exe]
)
This is the error I'm getting.
It looks like it is having trouble finding methods that belong to docx, but my source code calls import docx and it is listed as a dependent module in the setup file so I'm not sure why they aren't being included.
After a LOT of messing about I've finally cracked this. The docx module is dependent on lxml. Even though the raw .py file runs perfectly fine with just docx imported, when cx_freezing you need to explicitly state the dependency by adding lxml to the packages.

cx_Freeze help: is there a way to NOT make console open?

I am trying to convert a python game (made with pygame) into a exe file for windows, and I did using cx_Freeze. No problems there.
The thing is that when I launch myGame.exe, it opens the normal Pygame window and a console window(which I do not want).
Is there a way to remove the console window? I read most of the documentation, but I saw nothing really (except base, but I don't get what that is).
BTW, here is my setup file:
import cx_Freeze
exe = [cx_Freeze.Executable("myGame.py")]
cx_Freeze.setup(
name = "GameName",
version = "1.0",
options = {"build_exe": {"packages": ["pygame", "random", "ConfigParser", "sys"], "include_files": [
"images", "settings.ini", "arialbd.ttf"]}},
executables = exe
)
Here's a screen shot of what happens when I launch the exe:
So what was wrong, was that the setup.py file was missing a parameter.
What you need to add is base = "Win32GUI" to declare that you do not need a console window upon launch of the application.
Here's the code:
import cx_Freeze
exe = [cx_Freeze.Executable("myGame.py", base = "Win32GUI")] # <-- HERE
cx_Freeze.setup(
name = "GameName",
version = "1.0",
options = {"build_exe": {"packages": ["pygame", "random", "ConfigParser", "sys"],
"include_files": ["images", "settings.ini", "arialbd.ttf"]}},
executables = exe
)
The parameter can be passed also by the shell if you are making a quick executable
like this:
cxfreeze my_program.py --base-name=WIN32GUI

cx_freeze & bundling files

At present I am using pyinstaller for bundling my python application. I am equally migrating to pyGObject (due to pygtk being depreciated).
Now pyinstaller does not support pyGObject and I have as of yet not figured out the required hooks... One of the other downsides of pyinstaller is how it bundles into a single executable - it causes the company installed virus scanner to check quite intensively every time the exe is run ==> quite slow startup.
Looking into using cx_freeze due to the pyGObject & py3 support I note it does not have a single-executable option. That in itself isn't an issue if the working directory can be cleaned up, be it via the pyd/dll being bundled into a second zip or into a subdirectory.
Searching around (stackoverflow and other sites), it is illuded to that it can be done, but I am not getting the expected results. Any idea#s?
setup.py is based around this one: http://wiki.wxpython.org/cx_freeze
ok solved:
1) setup.py
import sys
from cx_Freeze import setup, Executable
EXE1 = Executable(
# what to build
script = "foo.py",
initScript = None,
base = 'Win32GUI',
targetDir = "dist",
targetName = "foo.exe",
compress = True,
copyDependentFiles = True,
appendScriptToExe = True,
appendScriptToLibrary = False,
icon = 'foo.ico'
)
setup(
version = "9999",
description = "...",
author = "...",
name = "...",
options = {"build_exe": {"includes": includes,
"excludes": excludes,
"packages": packages,
"path": sys.path,
"append_script_to_exe":False,
"build_exe":"dist/bin",
"compressed":True,
"copy_dependent_files":True,
"create_shared_zip":True,
"include_in_shared_zip":True,
"optimize":2,
}
},
executables = [EXE1]
)
2) foo.py header:
import os
import sys
if getattr(sys,'frozen',False):
# if trap for frozen script wrapping
sys.path.append(os.path.join(os.path.dirname(sys.executable),'bin'))
sys.path.append(os.path.join(os.path.dirname(sys.executable),'bin\\library.zip'))
os.environ['TCL_LIBRARY'] = os.path.join(os.path.dirname(sys.executable),'bin\\tcl')
os.environ['TK_LIBRARY'] = os.path.join(os.path.dirname(sys.executable),'bin\\tk')
os.environ['MATPLOTLIBDATA'] = os.path.join(os.path.dirname(sys.executable),'bin\\mpl-data')

How do I use cx_freeze?

I've created my setup.py file as instructed but I don't actually.. understand what to do next. Typing "python setup.py build" into the command line just gets a syntax error.
So, what do I do?
setup.py:
from cx_Freeze import setup, Executable
setup(
name = "On Dijkstra's Algorithm",
version = "3.1",
description = "A Dijkstra's Algorithm help tool.",
exectuables = [Executable(script = "Main.py", base = "Win32GUI")])
Add import sys as the new topline
You misspelled "executables" on the last line.
Remove script = on last line.
The code should now look like:
import sys
from cx_Freeze import setup, Executable
setup(
name = "On Dijkstra's Algorithm",
version = "3.1",
description = "A Dijkstra's Algorithm help tool.",
executables = [Executable("Main.py", base = "Win32GUI")])
Use the command prompt (cmd) to run python setup.py build. (Run this command from the folder containing setup.py.) Notice the build parameter we added at the end of the script call.
I'm really not sure what you're doing to get that error, it looks like you're trying to run cx_Freeze on its own, without arguments. So here is a short step-by-step guide on how to do it in windows (Your screenshot looks rather like the windows command line, so I'm assuming that's your platform)
Write your setup.py file. Your script above looks correct so it should work, assuming that your script exists.
Open the command line (Start -> Run -> "cmd")
Go to the location of your setup.py file and run python setup.py build
Notes:
There may be a problem with the name of your script. "Main.py" contains upper case letters, which might cause confusion since windows' file names are not case sensitive, but python is. My approach is to always use lower case for scripts to avoid any conflicts.
Make sure that python is on your PATH (read http://docs.python.org/using/windows.html)1
Make sure are are looking at the new cx_Freeze documentation. Google often seems to bring up the old docs.
I ran into a similar issue. I solved it by setting the Executable options in a variable and then simply calling the variable. Below is a sample setup.py that I use:
from cx_Freeze import setup, Executable
import sys
productName = "ProductName"
if 'bdist_msi' in sys.argv:
sys.argv += ['--initial-target-dir', 'C:\InstallDir\\' + productName]
sys.argv += ['--install-script', 'install.py']
exe = Executable(
script="main.py",
base="Win32GUI",
targetName="Product.exe"
)
setup(
name="Product.exe",
version="1.0",
author="Me",
description="Copyright 2012",
executables=[exe],
scripts=[
'install.py'
]
)
You can change the setup.py code to this:
from cx_freeze import setup, Executable
setup( name = "foo",
version = "1.1",
description = "Description of the app here.",
executables = [Executable("foo.py")]
)
I am sure it will work. I have tried it on both windows 7 as well as ubuntu 12.04
find the cxfreeze script and run it. It will be in the same path as your other python helper scripts, such as pip.
cxfreeze Main.py --target-dir dist
read more at:
http://cx-freeze.readthedocs.org/en/latest/script.html#script
I usually put the calling setup.py command into .bat file to easy recall.
Here is simple code in COMPILE.BAT file:
python setup.py build
#ECHO:
#ECHO . : ` . * F I N I S H E D * . ` : .
#ECHO:
#Pause
And the setup.py is organized to easy customizable parameters that let you set icon, add importe module library:
APP_NAME = "Meme Studio"; ## < Your App's name
Python_File = "app.py"; ## < Main Python file to run
Icon_Path = "./res/iconApp48.ico"; ## < Icon
UseFile = ["LANGUAGE.TXT","THEME.TXT"];
UseAllFolder = True; ## Auto scan folder which is same level with Python_File and append to UseFile.
Import = ["infi","time","webbrowser", "cv2","numpy","PIL","tkinter","math","random","datetime","threading","pathlib","os","sys"]; ## < Your Imported modules (cv2,numpy,PIL,...)
Import+=["pkg_resources","xml","email","urllib","ctypes", "json","logging"]
################################### CX_FREEZE IGNITER ###################################
from os import walk
def dirFolder(folderPath="./"): return next(walk(folderPath), (None, None, []))[1]; # [ Folder ]
def dirFile(folderPath="./"): return next(walk(folderPath), (None, None, []))[2]; # [ File ]
if UseAllFolder: UseFile += dirFolder();
import sys, pkgutil;
from cx_Freeze import setup, Executable;
BasicPackages=["collections","encodings","importlib"] + Import;
def AllPackage(): return [i.name for i in list(pkgutil.iter_modules()) if i.ispkg]; # Return name of all package
#Z=AllPackage();Z.sort();print(Z);
#while True:pass;
def notFound(A,v): # Check if v outside A
try: A.index(v); return False;
except: return True;
build_msi_options = {
'add_to_path': False,
"upgrade_code": "{22a35bac-14af-4159-7e77-3afcc7e2ad2c}",
"target_name": APP_NAME,
"install_icon": Icon_Path,
'initial_target_dir': r'[ProgramFilesFolder]\%s\%s' % ("Picox", APP_NAME)
}
build_exe_options = {
"includes": BasicPackages,
"excludes": [i for i in AllPackage() if notFound(BasicPackages,i)],
"include_files":UseFile,
"zip_include_packages": ["encodings"] ##
}
setup( name = APP_NAME,
options = {"build_exe": build_exe_options},#"bdist_msi": build_msi_options},#,
executables = [Executable(
Python_File,
base='Win32GUI',#Win64GUI
icon=Icon_Path,
targetName=APP_NAME,
copyright="Copyright (C) 2900AD Muc",
)]
);
The modules library list in the code above is minimum for workable opencv + pillow + win32 application.
Example of my project file organize:
========== U P D A T E ==========
Although cx_Freeze is a good way to create setup file. It's really consume disk space if you build multiple different software project that use large library module like opencv, torch, ai... Sometimes, users download installer, and receive false positive virus alert about your .exe file after install.
Thus, you should consider use SFX archive (.exe) your app package and SFX python package separate to share between app project instead.
You can create .bat that launch .py file and then convert .bat file to .exe with microsoft IExpress.exe.
Next, you can change .exe icon to your own icon with Resource Hacker: http://www.angusj.com/resourcehacker/
And then, create SFX archive of your package with PeaZip: https://peazip.github.io/
Finally change the icon.
The Python Package can be pack to .exe and the PATH register can made with .bat that also convertable to .exe.
If you learn more about command in .bat file and make experiments with Resource Hacker & self extract ARC in PeaZip & IExpress, you can group both your app project, python package into one .exe file only. It'll auto install what it need on user machine. Although this way more complex and harder, but then you can custom many install experiences included create desktop shorcut, and install UI, and add to app & feature list, and uninstall ability, and portable app, and serial key require, and custom license agreement, and fast window run box, and many more,..... but the important features you get is non virus false positive block, reduce 200MB to many GB when user install many your python graphic applications.

Categories

Resources