cx_freeze QtWebKit import error - python-3.x

My cx_freeze build was working correctly until I added one QWebView element into window. This means I should import QtWebKit, right? On Linux everything works perfectly. On Windows, if I run main.py file everything works perfectly.
If I freeze it into an .exe, this is the error I get . This is my install.py file:
from cx_Freeze import setup, Executable
includes=["re","PyQt4.QtWebKit"]
exe = Executable(
script="main.pyw",
base="Win32GUI",
targetName = "LEX.exe"
)
setup(
name = "blabla",
version = "1.3",
description = "My application",
options = {"build_exe": {"includes":includes}},
executables = [exe]
)
I am building it on x64 Windows 7, but with x86 versions of PyQt4 and Python3.2 x86. Before that QWebView element there were no problems at all.

Upgrading to cx_freeze 4.3 and editing the imports did the trick. Imports are now like this:
from PyQt4.QtNetwork import *
from PyQt4.QtWebKit import QWebView,QWebPage

You should not add imports (and possibly pollute your namespace) just to have cx_Freeze recognize the dependency.
Rather add PyQt4.QtNetwork to your "includes" list as you did with PyQt4.QtWebKit.
You can also include all modules of a package by using the "packages" option. That is, "packages" is for whole packages what "includes" is for modules.

Related

Python to EXE - PySide2 and Custom Modules

I'm trying to create an EXE from a Python project I built and I'm running into some issues. I've done this before with PyInstaller for simpler tools and cx-freeze for tools where I use custom modules but the way I used to set it up doesn't seem to be working anymore.
In this particular case I've tried:
cx-freeze==6.10
pyinstaller==4.10
py2exe==0.11.1.0
auto-py-to-exe==2.18.0
and a few others with no luck
Everything works perfectly fine through the Python 3.8 interpreter. I'm assuming it's either because of the way I'm importing PySide2 here (which I don't normally do but did for this project to see if it would speed up my programming time) or that the EXE modules can't find my custom modules. Here is a mock version of my program (names/paths changed for simplicity):
Example folder of my project ("C:\a\MyProjects\Project1"):
Example folder of the custom module I'm using. Each using various other built-in and/or 3rd party python modules. ("C:\a\path\to\external\modules"):
Example of my main file (C:\a\MyProjects\Project1\ui.py) I want to turn into an EXE:
import os
import sys
import colorsys
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *
import utils # module in project ("C:\a\MyProjects\Project1\utils.py")
sys.path.append(r"C:\a\path\to\external\modules") # custom module location for MyModule
from MyModule.foo import module1 as foo_mod1
from MyModule.foo import module2 as foo_mod2
from MyModule.bar import module1 as bar_mod1
from MyModule.bar import module2 as bar_mod2
from MyModule.baz import module1 as baz_mod1
from MyModule.baz import module2 as baz_mod2
class MainDialog(QDialog):
[...code...]
[...use of "dark.stylesheet"...]
[...use of "images\image 1.png"...]
[...use of "images\image 2.png"...]
def main():
global win
try: # try to close existing instances
win.close()
except NameError:
pass
win = MainDialog()
win.show()
if __name__ == "__main__":
app = QApplication.instance()
if not app:
app = QApplication(sys.argv)
main()
sys.exit(app.exec_())
Can someone tell me the best module and method to make this into a windowed (console-less), if possible, single file application. This is one of the more complicated tools I've had to make into a desktop app so if I can figure this out I should be good for most of the other things I have to do.
Thanks in advance.
EDIT:
Example of cx-freeze setup.py file in project I tried (C:\a\MyProjects\Project1\setup.py):
from cx_Freeze import setup, Executable
import sys
setup(
name="MyProject",
version="1.0",
options={'build_exe': {
'excludes': ["Tkinter"],
'includes': ["utils", "MyModule.foo", "MyModule.bar", "MyModule.baz"],
'path': sys.path + [r"C:\a\path\to\external\modules"],
'include_files': ["images\image 1.png", "images\image 2.png"],
'packages': ["PySide2.QtWidgets", "PySide2.QtCore", "PySide2.QtGui"]}},
executables=[Executable("ui.py", base="Win32GUI")]
Example of pyinstaller cmd command I tried:
cd C:\\a\MyProjects\Project1
pyinstaller -p "C:\a\path\to\external\modules" --onefile -w ui.py
# even tried this with a custom spec file like:
# pyinstaller --onefile -w ui.spec
There is a command in PyInstaller to include hidden modules call --hidden-module (You can use multile times). So, you can just do
pyinstaller -p "C:\a\path\to\external\modules" --onefile -w --hidden-module="example module 1" -hidden-module="example module 2" ui.py
This seems to have fixed itself after I got a new workstation and installed the latest Python (3.10) and Pyinstaller (5.1) versions.
Also think having your custom Python Libraries in the PYTHONPATH and/or PATH Environment variables may be important for allowing Pyinstaller to find them.

No module named 'tkinter' when trying to create exe file

I wrote some files in python and want to create an exe file. To do it with cx_freeze I create a setup.py file like that:
import sys
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = {"includes": ["tkinter"]}
# 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 = "LSR",
version = "0.1",
description = "",
options = {"build_exe": build_exe_options},
executables = [Executable("LS-R.py", base = base)])
then I write in the cmd :
python setup.py build
and I get this error:
error during GetDependentFiles() of "c:\users\appdata\local\programs\python\python36\dlls\tk86t.dll": (0, 'The system cannot find the file specified', 'c:\users\appdata\local\programs\python\python36\dlls\tk86t.dll', 2, None)
copying C:\Users\AppData\Local\Programs\Python\Python36\lib\site-packages\pywin32_system32\pywintypes36.dll -> build\exe.win-amd64-3.6\lib\pywintypes36.dll
copying C:\Users\AppData\Local\Programs\Python\Python36\lib\site-packages\pywin32_system32\pythoncom36.dll -> build\exe.win-amd64-3.6\lib\pythoncom36.dll
exe file created , but when I try open it I get this message :
ModuleNotFoundError:No module named 'tkinter'
someone know what is the problem? and what should I do to fix it? (I'm working in Windows OS)
Its Quite simple use;
pip install auto-py-to-exe
It will give you A GUI and is as simple as it gets. It is based on
Pyinstaller, cx-freeze, etc
See PyPI.
I was having the same problems even in Pyinstaller but this is the easiest way without any errors and is the most Effective way.
After Installation in cmd type
auto-py-to-exe
This will open a new Browser window with a beautiful and easy to use GUI.
It works for Tkinter well as I have used to to create like 50 Tkinter .exe files.
I made a program for activating windows in Tkinter with this;
See: https://drive.google.com/file/d/1RKLIlGcrra1pC5MyaPWrlQa1tW25Wc_q/view
I hope this makes your job quite easy.

Create executable with python 3.7 PyQt5 and cx_Freeze but DLL Failed to load

I developed a "not so simple" GUI with PyQt5 via Anaconda 3 (Python 3.7) and Designer.
I have 3 different .ui files that I import in my program.
When I run cx_Freeze, everything runs good, I create the .exe. Then, I copy the "platform" folder from my "Python" folder in the "Build" folder that cx_Freeze creates.
BUT, when I pass it to an other machine without anything on it (no anaconda, no python, no cx_Freeze, nothing), the app doesn't run. I get:
ImportError: DLL load failed: The specified module could not be found
It happens in the 10th line of my code which is:
from PyQt5 import QtGui, QtWidgets
The imports in my code are:
from PyQt5 import QtGui, QtWidgets
import sys
import glob
import datetime
from matplotlib.backends.qt_compat import QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure
import numpy as np
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import design
import flex
import entry
design, flex and entry are the .ui files. They all contain this part at the end (don't know if it helps):
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
And finally, the setup file I run with cx_Freeze:
import sys
from cx_Freeze import setup, Executable
import matplotlib
import numpy
# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = {"packages": ["os", "matplotlib"], "includes": ["PyQt5", "atexit"], "excludes": ["tkinter"]}
# 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 = "Flexicounts",
version = "0.1",
description = "Flexicounts pour faire tes comptes facilement",
options = {"build_exe": build_exe_options},
executables = [Executable("flexicounts.py", base=base)])
I read a lot about it, but I feel that there is no "miracle" solution...
Could you help me freeze my app and make it run on a "virgin machine" ?
You might be facing Issue #504 of the cx_Freeze repository. In that case, quoting a comment by marceloduarte there:
The workaround is to copy python3.dll to the directory where the executable was made. cx_Freeze copies python37.dll, but does not copy python3.dll. The vcruntime140.dll may also have to be copied when it no longer exists on the system.
First try to manually copy these DLLs (you find them in the directory of your python installation containing python.exe) to the directory of your executable. If that solves the problem, you can tell cx_Freeze to do it for you by using the include_files list of the build_exe_options. Modify you setup script as follows:
import os
python_dir = os.path.dirname(sys.executable) # directory of your python installation
build_exe_options = {"packages": ["os", "matplotlib"],
"includes": ["PyQt5", "atexit"],
"include_files": [os.path.join(python_dir, "python3.dll"), os.path.join(python_dir, "vcruntime140.dll")],
"excludes": ["tkinter"]}
Maybe you need to copy further DLLs, such as msvcp140.dll, or any other DLL present inside the site-packages/PyQt5 directory (including subdirectories) of your Python installation.
I faced a similar problem recently, with the following versions:
python 3.6.6 x64
cx-Freeze==6.10
PyQt5==5.15.4
PyQt5-Qt5==5.15.2
PyQt5-sip==12.9.0
PyQt5-stubs==5.15.2.0
PyQtWebEngine==5.15.5
PyQtWebEngine-Qt5==5.15.2
Symptoms :
The cx_Freeze package was successful and execution working fine on my machine, because (as I found later and explained below) I had Python 3.6 x64 installed on my machine and visibile via environement variables.
On an another machine, the package failed with the exact same error on first PyQt5 import:
ImportError: DLL load failed: The specified module could not be found
However, in my case, all the necessary dlls seemed all in the right place :
cx_Freeze seemed to have correctly put python3.dll and python36.dll next to the executable. But no other dll were copied there (no vcruntime140.dll for instance)
all the necessary python modules were in place, including PyQt5 and all its dlls
Solution that was working :
(I created a cx_Freeze issue)
Contrary to the other answer, I had to copy
python3.dll
(either from <cx_freeze_build_dir_target> or from python3.6.6 install dir ...)
(python36.dll works too but is much bigger)
into the following folders:
<cx_freeze_build_dir_target>/lib/PyQt5/
The corresponding cx_Freeze setup config for this would be to add this to the include_files list, in the following fashion.
Unfortunatly, this does not work due to cx_Freeze having an sort of exception file liste that includes python3.dll and prevents the actual copy via include_files. So, the copy should be performed manually, after full setup script execution...
# import pkgutil
from pathlib import Path
from glob import glob
import sys
# ... your stuff
#
includes_list = []
# your stuff
# ...
# pyqt5 force copy of pythonlib(s) into qt5 target dir
# may not work if you intend to zip pyqt5 ?
python_dir = Path(sys.executable).parent
python_dlls = [ Path(p) for p in glob(f"{python_dir.as_posix()}/python*.dll")]
pyqt_base_dir = Path("lib", "PyQt5")
# prepare cx_Freeze tuples (source file, target dir)
includes_list+= [ (p, pyqt_base_dir / p.name) for p in python_dlls ]
build_exe_options = {"packages" : ..., # your packages
"includes" : ..., # yours
"include_files": includes_list,
"excludes" : ... # yours
}

What DLL's I have to load for Gobject in cx_freeze

I have a little problem with cx_freeze and hoping one of you can help me. I have searched trough this wonderfull forum but I can't find the answer.
I have used cx_freeze before with python 3.3 and ktinker and that worked flawless.
Now I made a little tool with a bit more complex gui and tried Glade.
Building the gui with Glade works perfect for me and on Linux and Windows 7 the application I have made works fine (in python interpreter).
When I run python setup.py bdist_msi I don't see any faults but when I try to run the exe in windows I get this error window:
(I can't post images jet)
The last 4 lines are:
_load_backward_compatible
File "ExtentionLoader_gi_gi.py", line 22, in <module
File "ExtentionLoader_gi_gi.py", line 14, in_bootstrap_
ImportError: DLL load failed: The specified module could not be found
I don't use any plugins, exotic imports so the dll's I have to load are only the dll's for Gobject. The setup file I have made from an example on this forum. For my ktinker app I did not have to import any dll.
Finally the question: Is there a list of dll's somewhere that tells me what dll's I have to add?
And is there something wrong with my setup.py?
The code is nothing special but if you want to check it: https://github.com/EddenBeer/CodeGenerator
The imports in Python:
import csv import sys import datetime
from gi.repository import Gtk
Installed on Windows 7:
Python-3.4.2
cx_Freeze-4.3.3.win32-py3.4
pygi-aio-3.14.0_rev6-setup
Setup.py:
import os, site, sys
from cx_Freeze import setup, Executable
## Get the site-package folder, not everybody will install
## Python into C:\PythonXX
site_dir = site.getsitepackages()[1]
include_dll_path = os.path.join(site_dir, "gnome")
## Collect the list of missing dll when cx_freeze builds the app
missing_dll = ['libgtk-3-0.dll',
'libgdk-3-0.dll',
'libatk-1.0-0.dll',
'libcairo-gobject-2.dll',
'libgdk_pixbuf-2.0-0.dll',
'libjpeg-8.dll',
'libpango-1.0-0.dll',
'libpangocairo-1.0-0.dll',
'libpangoft2-1.0-0.dll',
'libpangowin32-1.0-0.dll',
'libgnutls-26.dll',
'libgcrypt-11.dll',
'libp11-kit-0.dll'
]
## We also need to add the glade folder, cx_freeze will walk
## into it and copy all the necessary files
glade_folder = 'glade'
## We need to add all the libraries too (for themes, etc..)
gtk_libs = ['etc', 'lib', 'share']
## Create the list of includes as cx_freeze likes
include_files = []
for dll in missing_dll:
include_files.append((os.path.join(include_dll_path, dll), dll))
## Let's add glade folder and files
include_files.append((glade_folder, glade_folder))
## Let's add gtk libraries folders and files
for lib in gtk_libs:
include_files.append((os.path.join(include_dll_path, lib), lib))
base = None
## Lets not open the console while running the app
if sys.platform == "win32":
base = "Win32GUI"
executables = [
Executable("CodeGenerator.py",
base=base
)
]
buildOptions = dict(
compressed = False,
includes = ["gi", "csv", "datetime",],
packages = ["gi"],
include_files = include_files
)
setup(
name = "Code Generator",
author = "Ed den Beer",
version = "1.0",
description = "Generating copy instructions for RsLogix5000 out of a list with tags in a CSV file",
options = dict(build_exe = buildOptions),
executables = executables
)
My problem is solved.
Looking for an answer if found a utility called ListDlls.exe.
In this link is explaned how to use it:
https://bitbucket.org/anthony_tuininga/cx_freeze/issue/92/pygi-and-cx_freeze-error

Images not showing when running a frozen pyqt app on another computer

I have a PyQt4 program that I froze using cx_freeze. The problem I am having is when I make a QGraphicsPixmapItem, which it is getting its' pixmap made from a SVG file, the Item gets made no problem, but the Pixmap doesn't load so there is no image just the item in the scene. The thing that confuses me is that this only happens when I am running it on a different computer than the one that built the exe. When I run the exe on the computer that built it the program works perfectly. Even when I try to run it on a computer with all the required python components and pyqt components installed on the computer, if it isn't the computer that built it, the pixmap is not loaded from the svg file. I am not sure if this is a problem with my cx_freeze setup.py file or if I need to change something in the main code so any help or just pointing me in the right direction will be great. My feeling is that something is getting messed up when cx_freeze is building it so I will paste the contents of my setup.py file below. Also I am running on Windows using Python v3.1.
from cx_Freeze import setup, Executable
files = ['drawings\\FULL', 'drawings\\PANEL', 'data.csv', 'panelData.csv']
binIncludes = ['C:\\Python31\\Lib\\site-packages\\PyQt4\\bin\\QtSvg4.dll']
includes = ['main', 'PunchDialog', 'ArrayDialog', 'PricingDialog', 'FontAndInputDialog', 'PanelSelector', 'PyQt4', 'os', 'sys', 'ctypes', 'csv']
packages = ['drawings']
path = ['C:\\Users\\Brock\\Documents\\Programming\\PanelDesigner\\DrawingFirst', 'C:\\Python31\\Lib', 'C:\\Python31\\Lib\\site-packages', 'C:\\Python31\\DLLs']
setup(
name = 'PanelBuilder',
version = '1.0',
description = 'Allows user to draw custom panel layouts.',
author = 'Brock Seabaugh',
options = {'build_exe': {'packages':packages, 'path':path, 'include_files':files, 'bin_includes':binIncludes, 'includes':includes}},
executables = [Executable('PanelBuilder.py')])
PS. Here is my file hierarchy(if that helps at all):
\DrawingFirst
Main .py file
All .py files for all custom dialogs used
\drawings
some modules used
\FULL
A bunch of SVG files used
\PANEL
More SVG files used
This is a nasty problem I have run into myself in the past.
Let me quote http://www.py2exe.org/index.cgi/Py2exeAndPyQt:
(I know you are using cx_freeze but I am sure you can adapt your script)
PyQt4 and image loading (JPG, GIF,
etc)
PyQt4 uses plugins to read those image
formats, so you'll need to copy the
folder PyQt4\plugins\imageformats to
appdir\imageformats. Like in the
above cases, you can use data_files
for this. This won't work with
bundle_files on.
If the plugins are not reachable, then
QPixmap.load/loadFromData will return
False when loading an image in those
formats.
testapp.py:
from PyQt4 import QtGui, QtSvg
import sys
app = QtGui.QApplication([])
wnd = QtSvg.QSvgWidget()
wnd.load("flower.svg")
wnd.show()
sys.exit(app.exec_())
setup.py:
from cx_Freeze import setup, Executable
files = ['flower.svg']
includes = ['sip', 'PyQt4.QtCore']
setup(
name = 'Example',
version = '1.337',
description = 'Allows user to see what I did there.',
author = 'something',
options = {'build_exe': {'include_files':files, 'includes':includes}},
executables = [Executable('testapp.py')])
I created this test app on a Windows 7 machine and copied it over to a Windows XP machine. I did not have to copy any dlls around - it worked just like that.
I've added a hook to cx_freeze that includes imageformats whenever PyQt4.QtGui is included in the original code. With imageformats in the right place, even the externally stored icons work.
https://bitbucket.org/anthony_tuininga/cx_freeze/pull-request/11/added-pyqt4qtgui-load-hook-that-adds/diff
For people coming here from Google: if you only use QtWebKit, you do need to copy the imageformats dir (which you find in PYTHONDIR\lib\site-packages\PyQt4\plugins) into your app dir. Specifying PyQt4.QtWebKit among the includes is not enough.

Resources