Closed trappitsch closed 3 months ago
Do you mind, after you make the changes, giving me an example? Truthfully I've never used a Python GUI on Windows so I don't quite understand the issues we are solving.
Happy to! I'll work out some changed and then make a more detailed write up on why and what. Thanks!
Okay, this seems to be working now. The docs are still missing and I need to test this on macos, but here's a more detailed write up on the issue
I packaged this GUI with PyApp
. On Linux (and presumably macos - to be tested) running the app by double clicking it works great, the GUI pops up, all fine. On windows however, along with the app, a console window shows up like here:
The problem, turns out, is really multiple problems:
#![windows_subsystem = "windows"]
is set as a top-level crate attribute.python.exe
and pythonw.exe
. The first is basically a binary that targets the console
subsystem, the second targets the windows
subsystem and can thus run python GUIs without a console displayed. More details here.Setting the top-level crate argument (RFC 1665) doesn't work for the purpose here, since a PyApp
packaged program has to target the console
subsystem (otherwise, installation messages, etc., disappear into nowhere).
Thus, the easy fix (but see below) is to run GUIs simply with pythonw.exe
instead of python.exe
. This can now be accomplished by setting PYAPP_IS_GUI = 1
, which will change the execution to pythonw.exe
(on windows only). This by itself still shows the console. The reason for this is that PyApp
runs the command in process.rs
with command.status()
, which will wait for the child to finish. I had to change this to command.spawn()
(for the GUI case only) and then do some error checking and exits. If the spawned child lives and does not die immediately, Ok(())
will be returned, upon which the console closes. During the spawning process, the console still briefly blinks on the screen, but I think this would be acceptable.
Well, it's prettier, but not ideal. The process still only displays as python
in the task manager and any icons, etc., associated with the program disappear, since these configurations if present, are attached to the PyApp
binary (which closed after spawning the GUI). A prettier solution would probably be to try and write a launcher, as discussed here. This is something I want to look into, but I'm not sure yet on how implement it. However, the way the current solution is written (by using an env variable), I think, is flexible enough in order to build on from here.
Apologies for the wordy explanation, I hope this makes things clearer. Let me know what you think. I'd understand if you think this is not a worthy enough improvement and/or outside of the scope of PyApp
, however, I think GUI support could be really fun for many applications!
Quick update: Tested this on macos and the console popped up there too. I'll fix that too, update docs, and keep you posted!
Thank you!
Okay, this is now working on macos as well, with the caveat that by default, the macos console does not close after the last command is terminated (noted in docs). Otherwise, all working as described above in windows, linux, and macos. I also cleaned up the commit history a bit, hope this helps. Let me know what you think and thanks!
Beautiful, I will be fixing the branch up and merging soon!
Awesome, thanks! I'm glad you enjoy the feature :)
Related to issue #96
This draft PR is an idea to solve the issue that when packaging a GUI and running it on Windows, a console window will be opened along with running the GUI. The PR is currently incomplete and needs the following (at least):
pythonw.exe
when in full isolation modepythonw
when on Windows and not when on Linux!pythonw
should also be executed on macos...For macos: According to here,
pythonw
only needs to be used when running on Python versions<3.9
.Opening this as a draft as a start for discussion.