I create a single file python application with Pyinstaller using --onefile parameters.
Everything work as expected but the startup time is around 10 seconds on my machine. The problems is that during the file unpacking process of Pyinstaller package there are no visual feedback, so you don't know if the application is starting or even if you really clicked the icon. This problem became worse if the machine is slow (on my test with a very old machine i need almost 20 seconds to see the first login of my application)
There is a way to create some splash screen or visual feedback (like a progress bar as on unpackers) during the Pyinstaller bootstrap sequence?
Please note the question is about Pyinstaller unpacking process BEFORE the real application will be executed not by the application itself that already has is own splash screen
thank you
19.01.2018 - UPDATE1
My application is FULL GUI so i prefer to not use the console as "visual feedback" during the unpacking process.
There is a beta version of the splash screen!
So just use your normal pyinstaller command in cmd and add:
--splash splashfile.png
adding --splash splashfile.png gave me high pink color shades on splash screen, so I used JPG image with some colored background and it worked very well.
another update we need to close splash, within our project code in any suitable place feasible for us, else splash screen remains on top of UI until application itself is closed.
try:
import pyi_splash
pyi_splash.update_text('UI Loaded ...')
pyi_splash.close()
except:
pass
and put this splash screen close code with in try block as it is needed only for package execution,
and can just pass on exception and proceed at the time of development runs.
Update:
More elegant way to close the splash screen
if '_PYIBoot_SPLASH' in os.environ and importlib.util.find_spec("pyi_splash"):
import pyi_splash
pyi_splash.update_text('UI Loaded ...')
pyi_splash.close()
log.info('Splash screen closed.')
reason for discarding try/except because, if you generate console exe then try/except will unnecessarily generates warnings, so to completely avoid warnings also, this can be a good check..
I have been battling with this problem myself. Unfortunately, there is no feasible solution to the problem other than using the ugly console (completely agree there).
The problem stems from the fact that until PyInstaller unpacks all the files into a temp dir, no scripts will be run. From my research, there is no way to alter this functionality using currently available options within PyInstaller. It would be nice if the community behind PyInstaller would make this a standard feature of the module, but until then we may have to explore other installer options.
Happy programming!
One simple solution might be to display the console window after launching the application, which will output the status of the PyInstaller Bootloader while it is being opened.
To display the console, use the --console flag (or edit the .spec file to contain console = True) when bundling your application. These options are documented in the PyInstaller doc file.
There is a pull request got pyinstaller... Actually, it is already merged into master. It adds this functionality: https://github.com/pyinstaller/pyinstaller/pull/4887
At the moment you will need to build the pyinstaller to have this, but it is feasible. I managed to do this for my project without any deep knowledge in c/c++ etc.
Related
Just when I thought I am 100% done with my app, turns out I was wrong. The app uses APScheduler to run several events at the same time and until now had been tested only in development mode, by bundling it in a single .exe file using Pyinstaller with the console visible for debugging purposes.
Very pleased I can finally remove the console window to distribute it to others, I was surprised to see that removing the console appears to mess up how APScheduler works. The times the tasks should be performed are wrong. Instead of the next time a task should run, it sets the current time, and no scheduled events are being executed. I have tried dragging it into the cmd to see if it shows any errors there, but it just stays blank. Everything else seems to be working fine, the GUI, the system tray code, the SQL tables, etc..
Briefly, the code I use is:
pyinstaller --add-data images.png;. --onefile --icon=trayicon.ico -w script.py
I also tried --windowed command. Funnily enough, --noconsole shows as an unrecognised argument.
I tried making it into a .pyw file but the same problem is observed.
Can anyone perhaps explain:
What actually happens on a deeper level when one removes the console/window from the executable? This might set me on the right path to figuring out the mess up with APScheduler.
Is there a way to just hide the console/window in the background, instead of removing it entirely?
PS: I am using Windows 10, Anaconda 3, Python 3.7.6, Spyder IDE
SOLUTION:
Still not sure why (the lack of) console messes up the programme, but if anyone encounters similar problem in the future, I fixed it by creating the .exe with a window, and HIDING the console window using the following command at the very start of my code:
import win32gui
win32gui.ShowWindow(win32gui.GetForegroundWindow(), win32con.SW_HIDE)
I'm asking help today because I'm new to Tkinter and Pyinstaller (and python in general) and I'm having troubles with it.
I have a simple app working with sqlite, tkinter and pyinstaller to compile all of this in an executable program, the entrance point of my program is a file named main.py
This file calls all the dependancies (like the sqlite module for python, tkinter and my other files like classes etc...)
I made a very simple interface, with a Hello World in a tkinter label and a button to go to page 2 which displays page2 (also in a label), just to see if I'm capable of making it all run and compile all of these pieces together.
I can run it throught my shell executing it like : python main.py and everything is working fine.
But when I run pyinstaller on my linux machine, and start executing the program, nothing appears, my database.db (sqlite database file) is created but I don't have any interface like when I run it with my shell. The thing is getting even worse on windows where, once I've my .exe it just opens a shell and crash after few seconds, not even creating the database.
What I did is I created a 'log file', in which I write the steps of the program.
As you can see on the following picture, the 2 first prints are wrote in my log file (on linux), so I think it crashes when I try to create the window.
If any of you have an idea on what I do wrong, I would really appreciate help :)
General
From the PyInstaller manual:
Before you attempt to bundle to one file, make sure your app works correctly when bundled to one folder. It is is much easier to diagnose problems in one-folder mode.
As the comments suggested, use a catch-all try/except block to log all exceptions to a file. That is probably the best way to see what is really happening. Make sure that the logfile is created in an existing location where you have the necessary permissions.
I would suggest to take advantage of the built-in logging module instead of creating your own. It can e.g. automatically add from which file a log line was created.
IMHO, it is probable that the failures on Linux and ms-windows have completely different causes. You should probably treat them as different issues.
Linux
When you use single file mode, that file is unpacked into a temporary folder, probably somewhere in /tmp. Some Linux distributions mount the /tmp filesystem with the noexec flag. This is incompatible with PyInstaller.
ms-windows
On windows, there are basically two different Pythons; python.exe and pythonw.exe. Basically it is one of the quirks of windows that this is necessary. The latter is for GUI programs like tkinter programs. A tkinter script should not show a cmd window. So I'm guessing that PyInstaller calls your command with python.exe instead of pythonw.exe. From the manual:
By default the bootloader creates a command-line console (a terminal window in GNU/Linux and Mac OS, a command window in Windows). It gives this window to the Python interpreter for its standard input and output. Your script’s use of print and input() are directed here. Error messages from Python and default logging output also appear in the console window.
An option for Windows and Mac OS is to tell PyInstaller to not provide a console window. The bootloader starts Python with no target for standard output or input. Do this when your script has a graphical interface for user input and can properly report its own diagnostics.
As noted in the CPython tutorial Appendix, for Windows a file extention of .pyw suppresses the console window that normally appears. Likewise, a console window will not be provided when using a myscript.pyw script with PyInstaller.
Also, on windows it can matter which Python distribution you're using. I used to be a fan of Anaconda, but lately I've come to prefer the python.org version because it gives me less headaches. On anaconda Python I had the problem that tkinter programs would not launch without showing a cmd window, whatever I tried. Only switching to python.org Python solved that problem.
I have an .exe I'm packaging using pyinstaller and it works like a charm. However when the .exe is clicked, I have to wait nearly 10 seconds while staring at a blank console window for the actual application to start.
From my research I've surmised that this is because of --onefile, and all the various files packaged in need to be unpacked before any code is run. I'm not concerned about the 10 second wait, but new users often need support because they think the program isn't working (reasonably so).
My ask is incredibly simple, but I can't figure out a way to do it: Is there anyway to get pyinstaller to run a tiny script BEFORE UNPACKING to just post a status blurb to the console, so users know that it's working?
As far as I know it is currently not possible to display custom messages before unpacking to let the user know the application is working. Source
There are a few workarounds to let the user know the program is working.
Display the console window
Displaying the console window after launching the application will output the status of the PyInstaller Bootloader while it is being opened.
To display the console, use the --console flag (or edit the .spec file to contain console = True) when bundling your application
Enable debug mode
To enable debug mode, use the --debug flag (or edit the .spec file to contain debug = True)
Example
exe = EXE(pyz,
//...
debug=True,
console=True )
You could always wrap your program into 7zip installer. You can add a quick shell script to say "Loading..." before running your main program or you could just edit config.txt to do the same.
How do I make a self extract and running installer
I have no idea if this problem has the solution I want but here goes.
I'm making a PyQt4 program that apparently needs the console window to run properly. However, whenever I activate another window, sending the program I'm working on to the back, the only way I can get back to it is by closing all the windows in front of said window. I can't just click on the taskbar because the only thing that comes back is the console window.
I'm curious. Is there a way to have the GUI window activate along with, or independent of, the console window without having to go through the annoying process of closing (minimizing) potentially all the rest of your windows?
Edit: I just realized my question is pretty vague. Let me elaborate.
I'm compiling said program using pyinstaller.
The reason it needs the console window to work properly (I have tried using the .pyw file as well, to no avail) is because there's another program that's the core of this one that prints out to it in a way I can only describe as violently.
Apparently it won't be happy unless it has the console to record it's outbursts.
That being said, I need the console window. However, as I mentioned before, that is the only thing that comes up when the pyinstaller icon is clicked.
There is a gui attached to the console, but there's no way to get it back even after the user would minimize it because the pyinstaller icon insists it doesn't exist.
Maybe it has something to do with how I defined the window while programming it, but I don't see why that would be the case. Is there something in particular pyinstaller doesn't like that would make it act like this?
How are you launching the PyQt application?
If you're launching it with the python executable, it will create a console.
python my_application.py
Instead, launch it with the GUI version of python -- pythonw:
pythonw my_application.py
If the python path isn't in the system path, you may need to specify the whole path to the executable:
C:\python27\pythonw.exe C:\path\to\my_application.py
I am new to python programming and development. After much self study through online tutorials I have been able to make a GUI with wxpython. This GUI interacts with a access database in my computer to load list of teams and employees into the comboboxes.
Now my first question is while converting the whole program into a windows exe file can I also include the .accdb file with it...as in I only need to send the exe file to the users and not the database..if yes how.
My second question is... I actually tried converting the program into exe using the py2exe (excluding the database...am not sure how to do that) and I got the .exe file of my program into the "Dist" folder. But when I double click it to run it a black screen (cmd) appears for less than a second and disappears. Please help me understand the above issue and resolve it.
am not sure if I have a option of attaching files...then I could have attached my wxpython program for reference.
Thanks in advance.
Regards,
Premanshu
The console could possibly appear if you used the 'console' parameter to setup(). Switch to 'windows' instead if that is the case. Can't say for sure without seeing your setup.py script. Possibly your app could also be opening console, but again hard to say without seeing source. One thing to check is to make sure you are not printing anything to stdout or stderr. You might want to redirect all of stdout and stderr to your log just in case, and do this right at the top of your start script so that if some 3rd party import was writing to stdout you'd be able to capture that.
The db is not part of your executable, so py2exe will not do anything with it. However, you should probably package your application with an installer, and you can make the installer include the db and install it along with the executable.