I searched for a way to hide a python caused window, for example a console or a ui window, so that you can't even see the open tab from this running application.So its like all actions of the python-program never have happend.
For example you do this:
print("Hello World")
and the user souldn't see anything of this:
But I found nothing, so does anybody know how this works?
Change the file extension of your python script file to '.pyw'. So, rename asdf.py to asdf.pyw.
This will make your script to be interpreted by a different executable than normal (precisely, pythonw.exe instead of python.exe).
Note that I do not know whether this works on other operating systems than Windows.
I finally found out a way to do this by using two modules:
*This works for cmd- and GUI-windows
import win32console # first module
import win32gui # secound one
win = win32console.GetConsoleWindow()
win32gui.ShowWindow(win, 0) # Hides the window
win32gui.ShowWindow(win, 1) # Shows the window
Edit: I found a second way to hide a terminal windows that is caused py python: All you have to do is to install pyinstaller with pip(3). Then write your sript, go to the command prompt and type in:
pyinstaller --onefile -w <sriptname>
-w = don't shows any console window (windows-less)
Related
When my script has the .pyw extension, the function subprocess.Popen doesn't work, but if I use the .py extension, it works. Actually the extension is not so important, the main point is if I use the terminal or not to run the script, if I don't use it I have the issue, otherwise no issues.
This wird behaviout happens only in my PC with Python 3.9.1 or 3.9.2 (the last version currently available). However I have another PC with Python 3.9.0, and there the issue doesn't exist.
I'll give you an example. here I have two scripts, below is the first one named main_script.pyw:
from tkinter import *
from tkinter import ttk
import sys, subprocess
def MyFunction():
subprocess.Popen(["start", sys.executable, "script.py"], shell=True)
parent=Tk()
parent.geometry("300x250+370+100")
parent.title("Test")
TestButton=ttk.Button(parent, text="start", width=16, command=MyFunction)
TestButton.place(x=10, y=10)
parent.mainloop()
Here is the second one named script.py:
a=input("give me a number: ")
Both of them are placed in the same directory. The user can start the second script using the function subprocess.Popen only if the extension of the main script is .py, otherwise he can't. How can I solve the issue? Is it a BUG?
I attached a GIF too:
UPDATE! 1
I tried to install Python 3.9.0 in a virtual machine, and there I found the same issue described before! so, I can't understand why in my PC, with the same version, the script works. if I type python --version in my terminal the output is Python 3.9.0. Here is another GIF to show you that it works:
In the installation path (C:\Users\USER_NAME\AppData\Local\Programs\Python), I saw two folders, Python39 and Python38-32. Probably the second one is a refuse from an old installation, I don't know, but maybe it helps to make the script work. What do you think?
I just want to run CLI scripts via Tkinter as you saw in the last GIF (without using the terminal of course). How can I reach my goal?
UPDATE! 2
I'm not sure but, maybe it's a Windows issue. I tried to run Google Chrome using the subprocess.Popen(["start", sys.executable, "script.py"], shell=True) instruction (before you have to open the terminal in the Chrome installation folder C:\Program Files\Google\Chrome\Application) and it worked only in my PC where I never have issues, but with the other one Chrome didn't start, and in the terminal I got this output (I use ConEmu as terminal):
>>> subprocess.Popen(["start", sys.executable, "chrome.exe"], shell=True)
<Popen: returncode: None args: ['start', 'C:\\Users\\aquer\\AppData\\Local\\...>
SyntaxError: Non-UTF-8 code starting with '\x83' in file C:\Program Files\Google\Chrome\Application\chrome.exe on line 2, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
Current directory:
C:\Program Files\Google\Chrome\Application
Command to be executed:
"C:\Users\USER_NAME\AppData\Local\Programs\Python\Python39\python.exe" chrome.exe
ConEmuC: Root process was alive less than 10 sec, ExitCode=1.
Press Enter or Esc to close console...
I tried to open the terminal in Admin mode but, also in this case, Google Chrome didn't start. Where is the issue from your point of viewes?
I think that it is because for .py files Windows uses python.exe and for .pyw files Windows uses pythonw.exe. The problem is that sys.executable has the file location of the program used to start the main python file (python.exe when the extension is .py and pythonw.exe when the extension is .pyw). So the problem is that you are trying to start the .py program using the python executable that is for .pyw file extensions.
In cmd:
>>> import sys
>>> sys.executable
'C:\\Program Files\\Python37\\python.exe'
in IDLE (doesn't have the terminal window):
>>> import sys
>>> sys.executable
'C:\\Program Files\\Python37\\pythonw.exe'
Therefore, you have to decide which program (python.exe or pythonw.exe) you want to use. You can do it based on the file extension.
A simple solution would be to open a command prompt from your main_script.py manually, and execute script.py in there, if you really have to execute it as an extra process. If you do not have to, just add import script at the place you want the content of script.py to be executed, or, even better, wrap the code in script.py into a function, import script.py at the top of main_script.py and call the funcction at the approproate place. For the first solution, there is an example on DataToFish that has almost the same code as you (using tkinter GUI a.o., you have to scroll down a bit to find the example with a GUI). In short, you just have execute cmd /c {sys.executable} script.pyw from main_script.py.
I am writing an IRC bot in Python.
I wish to make stand-alone binaries for Linux and Windows of it. And mainly I wish that when the bot initiates, the console window should hide and the user should not be able to see the window.
What can I do for that?
Simply save it with a .pyw extension. This will prevent the console window from opening.
On Windows systems, there is no notion of an “executable mode”. The Python installer automatically associates .py files with python.exe so that a double-click on a Python file will run it as a script. The extension can also be .pyw, in that case, the console window that normally appears is suppressed.
Explanation at the bottom of section 2.2.2
In linux, just run it, no problem. In Windows, you want to use the pythonw executable.
Update
Okay, if I understand the question in the comments, you're asking how to make the command window in which you've started the bot from the command line go away afterwards?
UNIX (Linux)
$ nohup mypythonprog &
Windows
C:/> start pythonw mypythonprog
I think that's right. In any case, now you can close the terminal.
On Unix Systems (including GNU/Linux, macOS, and BSD)
Use nohup mypythonprog &, and you can close the terminal window without disrupting the process. You can also run exit if you are running in the cloud and don't want to leave a hanging shell process.
On Windows Systems
Save the program with a .pyw extension and now it will open with pythonw.exe. No shell window.
For example, if you have foo.py, you need to rename it to foo.pyw.
This will hide your console. Implement these lines in your code first to start hiding your console at first.
import win32gui, win32con
the_program_to_hide = win32gui.GetForegroundWindow()
win32gui.ShowWindow(the_program_to_hide , win32con.SW_HIDE)
Update May 2020 :
If you've got trouble on pip install win32con on Command Prompt, you can simply pip install pywin32.Then on your python script, execute import win32.lib.win32con as win32con instead of import win32con.
To show back your program again win32con.SW_SHOW works fine:
win32gui.ShowWindow(the_program_to_hide , win32con.SW_SHOW)
If all you want to do is run your Python Script on a windows computer that has the Python Interpreter installed, converting the extension of your saved script from '.py' to '.pyw' should do the trick.
But if you're using py2exe to convert your script into a standalone application that would run on any windows machine, you will need to make the following changes to your 'setup.py' file.
The following example is of a simple python-GUI made using Tkinter:
from distutils.core import setup
import py2exe
setup (console = ['tkinter_example.pyw'],
options = { 'py2exe' : {'packages':['Tkinter']}})
Change "console" in the code above to "windows"..
from distutils.core import setup
import py2exe
setup (windows = ['tkinter_example.pyw'],
options = { 'py2exe' : {'packages':['Tkinter']}})
This will only open the Tkinter generated GUI and no console window.
Some additional info. for situations that'll need the win32gui solution posted by Mohsen Haddadi earlier in this thread:
As of python 361, win32gui & win32con are not part of the python std library.
To use them, pywin32 package will need to be installed; now possible via pip.
More background info on pywin32 package is at: How to use the win32gui module with Python?.
Also, to apply discretion while closing a window so as to not inadvertently close any window in the foreground, the resolution could be extended along the lines of the following:
try :
import win32gui, win32con;
frgrnd_wndw = win32gui.GetForegroundWindow();
wndw_title = win32gui.GetWindowText(frgrnd_wndw);
if wndw_title.endswith("python.exe"):
win32gui.ShowWindow(frgrnd_wndw, win32con.SW_HIDE);
#endif
except :
pass
After writing the code you want to convert the file from .py to .exe, so possibly you will use pyinstaller and it is good to make exe file. So you can hide the console in this way:
pyinstaller --onefile main.py --windowed
I used to this way and it works.
just change the file extension from .py to .pyw
As another answer for all upcoming readers:
If you are using Visual Studio as IDE, you can set "Window Application" in the Project settings with a single checkmark. Which is working with py-extension as well.
a decorator factory for this (windows version, unix version should be easier via os.fork)
def deco_factory_daemon_subprocess(*, flag_env_var_name='__this_daemon_subprocess__', **kwargs_for_subprocess):
def deco(target):
#functools.wraps(target)
def tgt(*args, **kwargs):
if os.environ.get(flag_env_var_name) == __file__:
target(*args, **kwargs)
else:
os.environ[flag_env_var_name] = __file__
real_argv = psutil.Process(os.getpid()).cmdline()
exec_dir, exec_basename = path_split(real_argv[0])
if exec_basename.lower() == 'python.exe':
real_argv[0] = shutil.which('pythonw.exe')
kwargs = dict(env=os.environ, stdout=subprocess.PIPE, stderr=subprocess.PIPE, )
kwargs.update(kwargs_for_subprocess)
subprocess.Popen(real_argv, **kwargs)
return tgt
return deco
use it like this:
#deco_factory_daemon_subprocess()
def run():
...
def main():
run()
Is there any way to run a Python 3 script without the terminal or the console popping out?
I tried many ways to hide the terminal at first run but even through I used .pyw extension, included a hide() function and used the --windowed flag when converting my script to an .exe through pyinstaller, the terminal still pops out for a microsecond before disappearing.
import win32console, win32gui
def hide():
window = win32console.GetConsoleWindow()
win32gui.ShowWindow(window, 0)
return True
I've read about a method in which you could run the python script through a C program to hide the terminal before execution but I would like to keep it as simple as I can.
Do you know any way to avoid the terminal flashing out when the script run?
you can hide the console window by using the .pyw extension for the file
I have a tkinter script, which runs just fine in IDLE. However, when I double click the .py-file from Windows Explorer, the console window flashes half a second and then it exits.
I was able to screenprint the console window. It says:
...etc.etc...
NameError: global name 'simpledialog' is not defined
simpledialog is a module in tkinter which I use in my script. As I do from tkinter import *, there is no need to explicitly write tkinter.simpledialog.
It works in IDLE, why not as .py?
IDLE uses Tkinter as its graphical environment. It is possible that your code is relying on a side effect of an import by IDLE itself. This is especially true if you use IDLE without a subprocess.
The simpledialog module does not import when using from tkinter import *.
Try adding this to your code:
import tkinter.simpledialog as simpledialog
Have you updated your PATH environment variable so that your Python executable is found? You can find more information on how to do here - Using Python on Windows
But you basically need to make sure that the folder containing python.exe (e.g. C:\Python32) is displayed when you type the following command from a prompt:
echo %PATH%
I had exactly the same problem with one of my scripts utilizing Tkinter.
Adding call to mainloop() fixed the issue.
See this tutorial for an example: [http://sebsauvage.net/python/gui/#import1
In my case, in the init function I have
def __init__(self,Width=400, Height=400):
# Create GUI window ------------------------------
win = Tk()
...
in the end of init I added:
win.mainloop()
Now it works by just running the file.
Hope this helps
Similar trouble for me just now, in my first week with python. But I dimly remembered a similar problem with a simple early test script and thought the trouble then was # comments.
So I tried that with my Tkinter infused .py script. It ran fine in IDLE as you say, then only flashed when clicked in windows. But there were a couple # commented lines at the top of file.
I took them all out and it now runs no sweat directly in windows. Have a look .. for #.
Sorry, can't seem to delete this post. Now the files work #comments included. Don't know what's up with that. ..
I found that changing the executable py file to a file.pyw fixed the problem. This tells python to execute it using the pythonw.exe which runs the script without the terminal/console in the background.
Not sure why this works, perhaps some screwed up environment variables from a previous python installation.
Changing the file's extension to pyw instead of py might solve the problem
I'm trying to hide the Terminal when I launch a GUI Tkinter based app, but when I double click the app.py file on OSX, the Terminal window appears. I've tried changing the extension to .pyw and tried launching it with /usr/bin/pythonw, but no matter what, the Terminal window still appears.
I've even tried adding the try/except below, but when I run it I get the error: 'invalid command name "console"' in the Terminal window that appears.
from Tkinter import *
class MainWindow(Tk):
def __init__(self):
Tk.__init__(self)
try:
self.tk.call('console', 'hide')
except TclError, err:
print err
win = MainWindow()
win.mainloop()
I haven't been able to find any way to hide the Terminal window from appearing. Anybody got any ideas?
By double-clicking a .py file on OS X, you are likely launching a Python gui instance via the Python Launcher.app supplied with OS X Pythons. You can verify that by selecting the .py file in the Finder and doing a Get Info on it. Python Launcher is a very simple-minded app that starts Python via a Terminal.app command. To directly launch your own Python GUI app, the preferred approach is to create a simple app using py2app. There's a brief tutorial here.
EDIT:
There are other ways, of course, but most likely any of them would be adding more levels of indirection. To make a normal launchable, "double-clickable" application, you need some sort of app structure. That's what py2app lets you create directly.
A very simple-minded alternative is to take advantage of the AppleScript Editor's ability to create a launcher app. In the AppleScript editor:
/Applications/Utilities/AppleScript
Editor.app in OS X 10.6
/Applications/AppleScript/Script
Editor.app in 10.5
make a new script similar to this:
do shell script "/path/to/python /path/to/script.py &> /dev/null &"
and then Save As.. with File Format -> Application. Then you'll have a double-clickable app that will launch another app. You can create something similar with Apple's Automater.app. But, under the covers, they are doing something similar to what py2app does for you, just with more layers on top.
Adding to the answer by Ned Deily, im my case when I tried to launch the Python application using an AppleScript application, it did not work initially. I discovered that it has something to to with some kind of encoding error (I am using UTF-8 and in the past I had felt need to configure it to UTF-8).
So, after further investigation, I discovered that I can accomplish this by creating an AppleScript application with the following code (adjusting the paths of python3 and of the Python application as needed):
do shell script "export LC_ALL=en_US.UTF-8; export LANG=en_US.UTF-8; /usr/local/bin/python3 '/Users/USER/FOLDER/SCRIPT.py' &> /dev/null &"
It launches the Python application without any Terminal windows. The AppleScript application can then be personalised with a custom icon as usual, and can be placed in the Dock. When clicked, it will launch the Python intepreter, that still shows up in Dock, but with no visible windows.
I think this may be useful to other users.
'console hide' doesn't hide the Terminal in OS X. It hides Tk's built-in console, which is really a relic from the MacOS Classic days (and which is still commonly used on Windows).