Package a GUI for distribution - ghostscript..? - python

I have a GUI created that I'd like to ship out to people I work with. The GUI works perfectly for me, but when I packaged it using pyinstaller and --onefile, it didn't work for anyone else. I am aware no one else has python installed on their machines, but I was told that wouldn't be a problem. However, my program involves ghostscript.
In short, my program has 3 buttons. Button 1 allows the user to select a pdf. Button 2 will convert this pdf into images. Button 3 will read each image and say whether it is a colour page or a black only page, when done it'll delete the temporary image files.
the imports i am using are
from tkinter import *
import os, time
from PyPDF2 import PdfFileReader, PdfFileWriter
from tempfile import NamedTemporaryFile
from tkinter.filedialog import askopenfilename, askdirectory
import tkinter.scrolledtext as tkst
from PythonMagick import Image as IMG
from PIL import Image
I think I'd somehow need to have the user install the same version of ghostscript as me when they open the application. Does anyone have any advice on how I can sort this out to have people use it?
EDIT: When I say 'it didn't work for anyone else', i mean the application opened, the user could select a file, but the button which runs the ghostscript stuff didn't work. Meaning ghostscript needed to be installed. After installed it worked.

I would suggest manual installation of GhostScript and adding its path to the OS environment.
import os
from pathlib import Path
this_path = Path(sys.argv[0]).parent
os.environ['MAGICK_HOME'] = ';'.join([str(this_path / 'image_magic'),
str(this_path / 'GhostScript' / 'bin')
])
Here, I install Image Magic + GhostScript in the root with the Python files.

Related

Pyinstaller onefile doesn't work on other computers

My role at work includes automating several processes which are easily automated via Python, for use by the entire team at the office. None of my coworkers have Python set up on their devices (we're all Windows) nor would they be comfortable using it if they did, so I've been compiling my work into .exe files with tkinter.
My most recent (and, of course, the most important) program compiles into a onefile .exe without issue, and runs perfectly on my computer. My coworkers are able to open it and load files into it, but when they go to activate some of the tkinter buttons within, one coworker has absolutely nothing happen while another gets a windows error message that the program has crashed. I'm unable to recreate these issues on my side.
The .exe was made using pyinstaller in a virtual environment, in which I installed all necessary dependencies. The script does not need to read or reference any other files in order to run. Is it possible that the .exe is still somehow missing a dependency that it's finding on my device and not others? How can I be sure? Would setting it up to include an installer wizard make a difference? Thanks for the help on this!
I can't include the full script due to character limit, but I've included the opening lines with all imports.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.fft import fft as fft
from scipy.fft import ifft as ifft
from tkinter import *
from tkinter import ttk
from tkinter import simpledialog
from tkinter import filedialog
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

importing local installation of PySide into Python

Have been searching for this for a while and trying different solutions, but nothing seems to fix my problem.
I am sitting on a unix server, and have installed PySide locally in my home directory, so python will not pick it up. (not added to PYTHONPATH?).
I am not able to import PySide in my python script.
Trying the following:
import sys
sys.path.append('~/PySide-1.2.4/pyside_build/py2.7-qt4.8.5-64bit-release/pyside/PySide/')
from PySide.QtCore import *
from PySide.QtGui import *
Not sure if I am appending the correct path. At least there is a init.py file there and QtCore.so, and other *.so files.
Is it still correct to import from PySide?

Python PIL import Mac compatiblity

I wonder now for a long time, can I redirect python imports.
So on my Machine I did:
pip install pil
and then I can do:
from PIL import Image
That works great but the problem is many programs just want Image, they want:
import Image
Now my question is can I "redirect" the above statement so that I can use import Image?
If that does not work, how could I make it work?
Basically you can use any of the methods mentioned here.
On my linux installation, PIL already uses one of those - there's a directory called PILcompat which has files like Image.py, and a file called PILcompat.pth which is used to tell python to add this directory to its module search path.
This way when
import Image
is executed, python finds PILcompat/Image.py which executes its contents -
from PIL.Image import *
I'm guessing either the .pth file or the directory are missing on your machine.

How to Install and Use TkDnD with Python Tkinter on OSX?

I've spent some time to search for workable solution to do Drag and Drop behavior with Python Tkinter on OSX platform, and the most possible solution found is TkDnD library.
http://sourceforge.net/projects/tkdnd/files/
However I cannot find any manual or guide about the installation and basically no sample on OSX. Can anyone share their experience with me?
Furthermore, is it not a good choice to use Tkinter as a GUI solution? My users are all OSX platform and Python is preinstalled on all these machines. Any good suggestion to find a native GUI support without additional installation? PyQT seems to be another choice, but not sure if it requires the additional installation on Client machine.
I got this working on both Windows (10) and OSX (10.11) by downloading:
A) Tk extensions tkdnd2.8 from https://sourceforge.net/projects/tkdnd/
B) Python wrapper TkinterDnD2 from https://sourceforge.net/projects/tkinterdnd/
On OSX:
1) Copy the tkdnd2.8 directory to /Library/Tcl
2) Copy the TkinterDnD2 directory to /Library/Frameworks/Python.framework/Versions/.../lib/python/site-packages
(Use the sudo command for copying files on OSX due to permissions.)
On Windows:
1) Copy the tkdnd2.8 directory to ...\Python\tcl
2) Copy the TkinterDnD2 directory to ...\Python\Lib\site-packages
And here's a simple test case based on python drag and drop explorer files to tkinter entry widget. The TkinterDnD2 download comes with much more robust examples.
import sys
if sys.version_info[0] == 2:
from Tkinter import *
else:
from tkinter import *
from TkinterDnD2 import *
def drop(event):
entry_sv.set(event.data)
root = TkinterDnD.Tk()
entry_sv = StringVar()
entry_sv.set('Drop Here...')
entry = Entry(root, textvar=entry_sv, width=80)
entry.pack(fill=X, padx=10, pady=10)
entry.drop_target_register(DND_FILES)
entry.dnd_bind('<<Drop>>', drop)
root.mainloop()
Update: the above procedure works for Python 2 or 3.
This is an update from 2017, with a bit more detail, since Mac decided to make it impossible to write files to /System/Library. The following solution is also cross-platform, since I am currently writing an app for both Windows/Mac that uses TkDnD.
The following solution works with pyInstaller, and also with Mac OS 10.12 and Windows 7.
First, we need to get a path to where tkDnD is. By default, I place tkdnd2.8 folder next to main.py.
import sys, os
if getattr(sys, 'frozen', False):
# If the application is run as a bundle, the pyInstaller bootloader
# extends the sys module by a flag frozen=True and sets the app
# path into variable _MEIPASS'.
application_path = sys._MEIPASS
else:
application_path = os.path.dirname(os.path.abspath(__file__))
TK_DND_PATH = os.path.join(application_path,'tkdnd2.8')
Note that Ellis's solution works Tcl directly, modifying the path. Make sure that SOMEWHERE, you have something along this gist:
import tkinter as tk
root = tk.Tk()
root.eval('lappend auto_path {' + TK_DND_PATH + '}')
After this, whenever you happen to actually import tkDnD, it will find it. I used DnD.py. Without the 'lappend auto_path' command, my program could never find tkDnD.
https://mail.python.org/pipermail/tkinter-discuss/2005-July/000476.html
2021 update
it annoyed me enough,so after the author did not responded I've forked the repo and built wheel for the latest compiled release(2.9.2) and upload it to pypi
you can now just do pip install tkinterdnd2 and it should work.
import is tkinterdnd2 and not Tkinterdnd2. see demos
I spent a few days to figured out how to install TkDnD lib, although it sounds like an easy question but did confused me a little while.
Two ways to install TkDnD on OSX:
A. Copy to /System/Library/Tcl/8.x:
OSX preinstalled Python already, and this is the path where Tcl library is installed. TkDnd lib will be loaded automatically while using Tk/Tcl lib.
B. Set os.environ['TKDND_LIBRARY'] to the location of TkDnd2.x.dylib:
Sample code:
if sys.platform == 'win32':
if getattr(sys, 'frozen', False):
os.environ['TKDND_LIBRARY'] = os.path.join(os.path.dirname(sys.executable), 'tkdnd2.7')
This is an update from 2020 for MacOS Catalina users.
Firstly, the tkdnd library project has been moved to github. The latest version is 2.9.3, and if you do not want to compile the library yourself the latest release is 2.9.2.
Secondly, placing the tkdnd lib on /Library/Tcl doesn't work anymore (you will get "error: tkdnd library not found"). With Catalina, python looks for the tkdnd lib in its own folder, that is /Library/Frameworks/Python.framework/Versions/.../lib. Placing the tkdnd2.9.3 folder in this path works just fine.
By the way, placing the TkinterDnD2 Python wrapper in /Library/Frameworks/Python.framework/Versions/.../lib/python/site-packages still works on Catalina.
Just to clarify, I only tested it for Python 3 (3.8.5), I do not know if for Python 2 the solution is the same but I suppose so.

Building an exe for a python script that uses Maya modules (Py2exe)

I know this is a long shot but I'm hoping someone on here has any experience with this as I can't find anything mentioning it online. I have a python script that imports modules from Autodesk Maya. This python script is run through mayapy.exe instead of python.exe which is whats throwing me off. I would rather not have to include a bat file with my script and have the users set the location of mayapy.exe in order to use it. I would prefer to somehow package mayapy.exe with my script using something like py2exe. I'm a little lost on where to go from here honestly.
If I run py2exe normally on my script, its result gives me the error cannot find maya.cmds, as expected. Is there a way I can find the dll to include? I tried running Dependency walker on mayapy.exe but I'm venturing into new territory here. There were only 2 dll's used from the Maya install directory base.dll and python26.dll, the rest were all system dlls. If anyone has tried any of this please share or if anyone has any advice or path I can look down or a website I can go to I would be very grateful. Thanks so much!
P.s. In case it helps at all, this is the python script imports:
try:
import maya.standalone
maya.standalone.initialize()
except:
pass
import maya.cmds as cmds
import maya.mel as mel
from time import time as tTime
from glob import iglob
from shutil import copy
from os.path import join
from PyQt4 import QtCore
from PyQt4 import QtGui
The point of the script is to create a maya file, do some things in it, then save it. Using the maya interpreter(mayapy.exe) it does this without ever opening maya, which is what I was wanting.
Pretty sure what I wanted to do was not possible. Instead I split my program into two parts, one requiring Maya one not, for the part requiring Maya I just had it do a registry lookup for the Maya install location and used that. If it were possibly to include the necessary files for my script, I'm sure Autodesk would not have approved in the first place anyways.

Categories