Is there any GUI programs that work like this - click button in GUI and it does launch some python code line or multiple lines, i thought about tkinter, but i found none options to make it launch some python code or is there?
Upd - In terminal code will be too complicated to use the code so i need GUI.
There are a few ways to run python code, the way it is required in the OP -:
Using exec or eval to run python code dynamically(NOTE: This would not
return the output but rather directly run the code as if it were
normal code.), Also note that use of exec and eval should generally be avoided but it had to be mentioned here as a possible way through.
exec(object, globals, locals)
eval(expression[, globals[, locals]])
Launching a terminal window(using os.system method of the os module) and using pyautogui to type and run the
command that executes given python script, when a button is
clicked(NOTE: With this method as well you will only be able to see
the output of the script but not fetch it.)
# required imports
import os, pyautogui
import tkinter as tk
from tkinter import filedialog
root = tk.Tk() # initializing the tkinter window.
def ask_for_running_file(event = None) :
filetypes = (("python files", '.py'), ("all files","*.*"))
filename = filedialog.askopenfilename(initialdir = '/', title = "Select file", filetypes = filetypes) # Get the name of the
python file to run.
addr_command = 'start cmd /k "cd "' + filename[ : filename.rindex('/')] # Command used to open the terminal
run_command = ' python \"' + filename[(filename.rindex('/') + 1) : ] + '\"' # The command to be typed in the terminal using pyautogui to execute the python script.
os.system(addr_command) # Runs the command required to open the terminal window.
pyautogui.write(run_command, interval = 0.25) # Writes the command required to execute the python script letter by letter.
NOTE: The interval here can be adjusted as per use case.
pyautogui.press('enter') # Pressing enter to execute the run command.
return
b1 = tk.Button(root, text = 'run file', command = ask_for_running_file) # The button that open a file dialog to choose
#which file to run.
b1.pack() # managing the geometry of the button.
root.mainloop() # starting mainloop
Use subprocess module to get the output of the execution of a
terminal command and then display it using tkinter or any other
module(if required). Note that the subprocess module suggests to use
the run function for most of the use cases so the example provided
below will involve the use of that only. The documentation lists the use of each and every argument and can be used further to modify the below code as pleased.
result = subprocess.run(['python', '\"' + script_name + '\"'],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell = True)
Once the way of executing the command is figured out, the button that triggers it and the GUI can be designed in any module as pleased, for example the function shown in method 2 can be used with any other GUI module's button's callback function too! And it should work fine keeping in mind to remove the use of tkinter filedialog within the function rest can stay the same.
NOTE:
The second method might not always work if there is a disturbance while pyautogui types in the command, and thus it is not suitable for use cases where background processes are needed to achieve the problem's solution.
Related
I have a python script I made a couple of months ago that is command line based. I want to make an optional GUI for it. It is a fairly basic program, it fetches cue files for game roms. I coded the GUI separately, and it came to mind that instead of trying to implement it into the code of the program, it'd be 10 times easier to just execute the program with the flags the user specified on the GUI, then print the output on a text field. This is the GUI:
The program parses flags with the argparse library. It has a positional argument which is the directory, and two optional flags being -r and -g (I guess you can identify which is which). How could I do it?
You can use subprocess.check_output() to get the output of a subprocess. Here's sample usage:
var = subprocess.check_output(
['python3', 'CueMaker.py'], shell=True, stderr=subprocess.STDOUT
)
# redirects the standrad error buffer to standrad output to store that in the variable.`
Then I can use var to change the text, assuming there's a StringVar() tied to the widget:
stringVar.set(var)
I have a simple script which parses a file and loads it's contents to a database. I don't need a UI, but right now I'm prompting the user for the file to parse using raw_input which is most unfriendly, especially because the user can't copy/paste the path. I would like a quick and easy way to present a file selection dialog to the user, they can select the file, and then it's loaded to the database. (In my use case, if they happened to chose the wrong file, it would fail parsing, and wouldn't be a problem even if it was loaded to the database.)
import tkFileDialog
file_path_string = tkFileDialog.askopenfilename()
This code is close to what I want, but it leaves an annoying empty frame open (which isn't able to be closed, probably because I haven't registered a close event handler).
I don't have to use tkInter, but since it's in the Python standard library it's a good candidate for quickest and easiest solution.
Whats a quick and easy way to prompt for a file or filename in a script without any other UI?
Tkinter is the easiest way if you don't want to have any other dependencies.
To show only the dialog without any other GUI elements, you have to hide the root window using the withdraw method:
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename()
Python 2 variant:
import Tkinter, tkFileDialog
root = Tkinter.Tk()
root.withdraw()
file_path = tkFileDialog.askopenfilename()
You can use easygui:
import easygui
path = easygui.fileopenbox()
To install easygui, you can use pip:
pip3 install easygui
It is a single pure Python module (easygui.py) that uses tkinter.
Try with wxPython:
import wx
def get_path(wildcard):
app = wx.App(None)
style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
dialog = wx.FileDialog(None, 'Open', wildcard=wildcard, style=style)
if dialog.ShowModal() == wx.ID_OK:
path = dialog.GetPath()
else:
path = None
dialog.Destroy()
return path
print get_path('*.txt')
pywin32 provides access to the GetOpenFileName win32 function. From the example
import win32gui, win32con, os
filter='Python Scripts\0*.py;*.pyw;*.pys\0Text files\0*.txt\0'
customfilter='Other file types\0*.*\0'
fname, customfilter, flags=win32gui.GetOpenFileNameW(
InitialDir=os.environ['temp'],
Flags=win32con.OFN_ALLOWMULTISELECT|win32con.OFN_EXPLORER,
File='somefilename', DefExt='py',
Title='GetOpenFileNameW',
Filter=filter,
CustomFilter=customfilter,
FilterIndex=0)
print 'open file names:', repr(fname)
print 'filter used:', repr(customfilter)
print 'Flags:', flags
for k,v in win32con.__dict__.items():
if k.startswith('OFN_') and flags & v:
print '\t'+k
Using tkinter (python 2) or Tkinter (python 3) it's indeed possible to display file open dialog (See other answers here). Please notice however that user interface of that dialog is outdated and does not corresponds to newer file open dialogs available in Windows 10.
Moreover - if you're looking on way to embedd python support into your own application - you will find out soon that tkinter library is not open source code and even more - it is commercial library.
(For example search for "activetcl pricing" will lead you to this web page: https://reviews.financesonline.com/p/activetcl/)
So tkinter library will cost money for any application wanting to embedd python.
I by myself managed to find pythonnet library:
Overview here: http://pythonnet.github.io/
Source code here: https://github.com/pythonnet/pythonnet
(MIT License)
Using following command it's possible to install pythonnet:
pip3 install pythonnet
And here you can find out working example for using open file dialog:
https://stackoverflow.com/a/50446803/2338477
Let me copy an example also here:
import sys
import ctypes
co_initialize = ctypes.windll.ole32.CoInitialize
# Force STA mode
co_initialize(None)
import clr
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import OpenFileDialog
file_dialog = OpenFileDialog()
ret = file_dialog.ShowDialog()
if ret != 1:
print("Cancelled")
sys.exit()
print(file_dialog.FileName)
If you also miss more complex user interface - see Demo folder
in pythonnet git.
I'm not sure about portability to other OS's, haven't tried, but .net 5 is planned to be ported to multiple OS's (Search ".net 5 platforms", https://devblogs.microsoft.com/dotnet/introducing-net-5/ ) - so this technology is also future proof.
If you don't need the UI or expect the program to run in a CLI, you could parse the filepath as an argument. This would allow you to use the autocomplete feature of your CLI to quickly find the file you need.
This would probably only be handy if the script is non-interactive besides the filepath input.
Another os-agnostic option, use pywebview:
import webview
def webview_file_dialog():
file = None
def open_file_dialog(w):
nonlocal file
try:
file = w.create_file_dialog(webview.OPEN_DIALOG)[0]
except TypeError:
pass # user exited file dialog without picking
finally:
w.destroy()
window = webview.create_window("", hidden=True)
webview.start(open_file_dialog, window)
# file will either be a string or None
return file
print(webview_file_dialog())
Environment: python3.8.6 on Mac - though I've used pywebview on windows 10 before.
I just stumbled on this little trick for Windows only: run powershell.exe from subprocess.
import subprocess
sys_const = ssfDESKTOP # Starts at the top level
# sys_const = 0x2a # Correct value for "Program Files (0x86)" folder
powershell_browse = "(new-object -COM 'Shell.Application')."
powershell_browse += "BrowseForFolder(0,'window title here',0,sys_const).self.path"
ret = subprocess.run(["powershell.exe",powershell_browse], stdout=subprocess.PIPE)
print(ret.stdout.decode())
Note the optional use of system folder constants. (There's an obscure typo in shldisp.h that the "Program Files (0x86)" constant was assigned wrong. I added a comment with the correct value. Took me a bit to figure that one out.)
More info below:
System folder constants
I was making a program that opens a file and does a few things to it, and I wondered if there was a way that you could click on a file, and it would open it in the program, instead of going into the program, clicking open, and navigation through the files to find it, or just a way where you can click "Open With..." and select your program. Here is the code if it helps:
from tkinter import *
from tkinter import filedialog
from subprocess import *
import os
root = Tk()
root.title("Snake converter")
def open_file():
filename = filedialog.askopenfilename(filetypes = (("Snake files", "*.sim"),("Python Files", "*.py"),("All files", "*.*")))
filenametmp = filename + ".tmp"
print filename + " is being compiled. Please wait..."
tf = open(filenametmp, "a")
f = open(filename, "r")
filecontents = f.read()
tf.write("from simincmodule import *" + "\n")
tf.write(filecontents)
os.chdir("C:\Snake\info\Scripts")
print os.getcwd()
call(["pyinstaller", filenametmp])
os.remove("C:/Snake/info/Scripts/build")
f.close()
tf.close()
print "\n\n----------------------------------------------------------------------\n\nFinished compiling " + filename + ". Find the program under [filename]/[filename].exe"
openbutton = Button(root, text = "Open", width = 10, command = open_file)
openbutton.pack()
root.mainloop()
Any help or suggestion will be highly appreciated.
Thanks!
"Open with..." usually sends the pathname of the file to sys.argv. So at an appropriate place of your program, add this:
if len(sys.argv) > 1:
open_file(sys.argv[1])
(As I said in the comment, you really want to let your open_file take an argument, and have another function like open_file_dialog to open the dialog.)
That leaves the question of how to make something you can "Open with..." in the first place. If you are on Windows, you should be able to achieve finer control with file association by editing the registry: see this MSDN page for details.
Alternatively, a quick-and-dirty way to do it is to make a .bat script that takes an argument and passes it to your python program. I remember doing this some time ago, but I haven't used Windows seriously for a long time, so I can't tell you how to write the script right off my head.
I am a Fan of Autohotkey Tools And Python Launguages,
An Other Way to do it, is:
If you want to run a program, and then Want to opened it with a file ("Open With...")
You can Think about,
Making your own Computer Movements Scripts With Keyboard Shortcuts Macros.
Step 1: Install (Python27) on your Windows System. Click Here
Step 2: Then Install the Python Packages - pyautogui and pywinauto
You can Use this Msdos Batch Script:
Install.bat
C:\Python27\scripts\pip.exe install pyautogui
pause
C:\Python27\scripts\pip.exe install pywinauto
pause
Now You are Ready, To Make and use this Python Script:
Example1.pyw
#run Notepad with "Open..."
#######################
import pywinauto
pywinauto.Application().start(r"C:\Windows\System32\Notepad.exe c:\test\test.txt")
#######################
Example2.pyw
#run Notepad
#######################
import pywinauto
pywinauto.Application().start("C:\Windows\System32\Notepad.exe")
#######################
#Open a File - "Open With..."
#######################
import pyautogui
import time
time.sleep(2)
pyautogui.hotkey('ctrl','o') #Many Programs use Shortcut Ctrl+o to "Open With..."
time.sleep(.750)
pyautogui.typewrite('c:\\test\\test.txt',0)
time.sleep(2)
pyautogui.hotkey('enter')
#######################
# you can send any text or Keyboard Shortcuts Combinations - Example Copy - pyautogui.hotkey('ctrl', 'c')
Note: If you use a File Path with typewrite Command - You Can Not put a ( single backslash \ ) you must replace it into a ( double backslash \\ )
Tip : Python Languages together with AutoPythonlauncher Software is a good Combination - If You Want to make, Toolbars On your Windows Desktop - Executeable Pictures with Python Scripts For Mouse or Touch Device. - For more info look at Homepage
How I would do it:
Make it so that your program reads from stdin and writes to stdout
Use the power of the shell. If you are in a unix shell, just simply do
cat infile | ./python myProgram.py > outfile
This will give the contents of infile to your program on stdin, then write the output of stdout to outfile.
I have a simple script which parses a file and loads it's contents to a database. I don't need a UI, but right now I'm prompting the user for the file to parse using raw_input which is most unfriendly, especially because the user can't copy/paste the path. I would like a quick and easy way to present a file selection dialog to the user, they can select the file, and then it's loaded to the database. (In my use case, if they happened to chose the wrong file, it would fail parsing, and wouldn't be a problem even if it was loaded to the database.)
import tkFileDialog
file_path_string = tkFileDialog.askopenfilename()
This code is close to what I want, but it leaves an annoying empty frame open (which isn't able to be closed, probably because I haven't registered a close event handler).
I don't have to use tkInter, but since it's in the Python standard library it's a good candidate for quickest and easiest solution.
Whats a quick and easy way to prompt for a file or filename in a script without any other UI?
Tkinter is the easiest way if you don't want to have any other dependencies.
To show only the dialog without any other GUI elements, you have to hide the root window using the withdraw method:
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename()
Python 2 variant:
import Tkinter, tkFileDialog
root = Tkinter.Tk()
root.withdraw()
file_path = tkFileDialog.askopenfilename()
You can use easygui:
import easygui
path = easygui.fileopenbox()
To install easygui, you can use pip:
pip3 install easygui
It is a single pure Python module (easygui.py) that uses tkinter.
Try with wxPython:
import wx
def get_path(wildcard):
app = wx.App(None)
style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
dialog = wx.FileDialog(None, 'Open', wildcard=wildcard, style=style)
if dialog.ShowModal() == wx.ID_OK:
path = dialog.GetPath()
else:
path = None
dialog.Destroy()
return path
print get_path('*.txt')
pywin32 provides access to the GetOpenFileName win32 function. From the example
import win32gui, win32con, os
filter='Python Scripts\0*.py;*.pyw;*.pys\0Text files\0*.txt\0'
customfilter='Other file types\0*.*\0'
fname, customfilter, flags=win32gui.GetOpenFileNameW(
InitialDir=os.environ['temp'],
Flags=win32con.OFN_ALLOWMULTISELECT|win32con.OFN_EXPLORER,
File='somefilename', DefExt='py',
Title='GetOpenFileNameW',
Filter=filter,
CustomFilter=customfilter,
FilterIndex=0)
print 'open file names:', repr(fname)
print 'filter used:', repr(customfilter)
print 'Flags:', flags
for k,v in win32con.__dict__.items():
if k.startswith('OFN_') and flags & v:
print '\t'+k
Using tkinter (python 2) or Tkinter (python 3) it's indeed possible to display file open dialog (See other answers here). Please notice however that user interface of that dialog is outdated and does not corresponds to newer file open dialogs available in Windows 10.
Moreover - if you're looking on way to embedd python support into your own application - you will find out soon that tkinter library is not open source code and even more - it is commercial library.
(For example search for "activetcl pricing" will lead you to this web page: https://reviews.financesonline.com/p/activetcl/)
So tkinter library will cost money for any application wanting to embedd python.
I by myself managed to find pythonnet library:
Overview here: http://pythonnet.github.io/
Source code here: https://github.com/pythonnet/pythonnet
(MIT License)
Using following command it's possible to install pythonnet:
pip3 install pythonnet
And here you can find out working example for using open file dialog:
https://stackoverflow.com/a/50446803/2338477
Let me copy an example also here:
import sys
import ctypes
co_initialize = ctypes.windll.ole32.CoInitialize
# Force STA mode
co_initialize(None)
import clr
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import OpenFileDialog
file_dialog = OpenFileDialog()
ret = file_dialog.ShowDialog()
if ret != 1:
print("Cancelled")
sys.exit()
print(file_dialog.FileName)
If you also miss more complex user interface - see Demo folder
in pythonnet git.
I'm not sure about portability to other OS's, haven't tried, but .net 5 is planned to be ported to multiple OS's (Search ".net 5 platforms", https://devblogs.microsoft.com/dotnet/introducing-net-5/ ) - so this technology is also future proof.
If you don't need the UI or expect the program to run in a CLI, you could parse the filepath as an argument. This would allow you to use the autocomplete feature of your CLI to quickly find the file you need.
This would probably only be handy if the script is non-interactive besides the filepath input.
Another os-agnostic option, use pywebview:
import webview
def webview_file_dialog():
file = None
def open_file_dialog(w):
nonlocal file
try:
file = w.create_file_dialog(webview.OPEN_DIALOG)[0]
except TypeError:
pass # user exited file dialog without picking
finally:
w.destroy()
window = webview.create_window("", hidden=True)
webview.start(open_file_dialog, window)
# file will either be a string or None
return file
print(webview_file_dialog())
Environment: python3.8.6 on Mac - though I've used pywebview on windows 10 before.
I just stumbled on this little trick for Windows only: run powershell.exe from subprocess.
import subprocess
sys_const = ssfDESKTOP # Starts at the top level
# sys_const = 0x2a # Correct value for "Program Files (0x86)" folder
powershell_browse = "(new-object -COM 'Shell.Application')."
powershell_browse += "BrowseForFolder(0,'window title here',0,sys_const).self.path"
ret = subprocess.run(["powershell.exe",powershell_browse], stdout=subprocess.PIPE)
print(ret.stdout.decode())
Note the optional use of system folder constants. (There's an obscure typo in shldisp.h that the "Program Files (0x86)" constant was assigned wrong. I added a comment with the correct value. Took me a bit to figure that one out.)
More info below:
System folder constants
I have a simple script which parses a file and loads it's contents to a database. I don't need a UI, but right now I'm prompting the user for the file to parse using raw_input which is most unfriendly, especially because the user can't copy/paste the path. I would like a quick and easy way to present a file selection dialog to the user, they can select the file, and then it's loaded to the database. (In my use case, if they happened to chose the wrong file, it would fail parsing, and wouldn't be a problem even if it was loaded to the database.)
import tkFileDialog
file_path_string = tkFileDialog.askopenfilename()
This code is close to what I want, but it leaves an annoying empty frame open (which isn't able to be closed, probably because I haven't registered a close event handler).
I don't have to use tkInter, but since it's in the Python standard library it's a good candidate for quickest and easiest solution.
Whats a quick and easy way to prompt for a file or filename in a script without any other UI?
Tkinter is the easiest way if you don't want to have any other dependencies.
To show only the dialog without any other GUI elements, you have to hide the root window using the withdraw method:
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename()
Python 2 variant:
import Tkinter, tkFileDialog
root = Tkinter.Tk()
root.withdraw()
file_path = tkFileDialog.askopenfilename()
You can use easygui:
import easygui
path = easygui.fileopenbox()
To install easygui, you can use pip:
pip3 install easygui
It is a single pure Python module (easygui.py) that uses tkinter.
Try with wxPython:
import wx
def get_path(wildcard):
app = wx.App(None)
style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
dialog = wx.FileDialog(None, 'Open', wildcard=wildcard, style=style)
if dialog.ShowModal() == wx.ID_OK:
path = dialog.GetPath()
else:
path = None
dialog.Destroy()
return path
print get_path('*.txt')
pywin32 provides access to the GetOpenFileName win32 function. From the example
import win32gui, win32con, os
filter='Python Scripts\0*.py;*.pyw;*.pys\0Text files\0*.txt\0'
customfilter='Other file types\0*.*\0'
fname, customfilter, flags=win32gui.GetOpenFileNameW(
InitialDir=os.environ['temp'],
Flags=win32con.OFN_ALLOWMULTISELECT|win32con.OFN_EXPLORER,
File='somefilename', DefExt='py',
Title='GetOpenFileNameW',
Filter=filter,
CustomFilter=customfilter,
FilterIndex=0)
print 'open file names:', repr(fname)
print 'filter used:', repr(customfilter)
print 'Flags:', flags
for k,v in win32con.__dict__.items():
if k.startswith('OFN_') and flags & v:
print '\t'+k
Using tkinter (python 2) or Tkinter (python 3) it's indeed possible to display file open dialog (See other answers here). Please notice however that user interface of that dialog is outdated and does not corresponds to newer file open dialogs available in Windows 10.
Moreover - if you're looking on way to embedd python support into your own application - you will find out soon that tkinter library is not open source code and even more - it is commercial library.
(For example search for "activetcl pricing" will lead you to this web page: https://reviews.financesonline.com/p/activetcl/)
So tkinter library will cost money for any application wanting to embedd python.
I by myself managed to find pythonnet library:
Overview here: http://pythonnet.github.io/
Source code here: https://github.com/pythonnet/pythonnet
(MIT License)
Using following command it's possible to install pythonnet:
pip3 install pythonnet
And here you can find out working example for using open file dialog:
https://stackoverflow.com/a/50446803/2338477
Let me copy an example also here:
import sys
import ctypes
co_initialize = ctypes.windll.ole32.CoInitialize
# Force STA mode
co_initialize(None)
import clr
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import OpenFileDialog
file_dialog = OpenFileDialog()
ret = file_dialog.ShowDialog()
if ret != 1:
print("Cancelled")
sys.exit()
print(file_dialog.FileName)
If you also miss more complex user interface - see Demo folder
in pythonnet git.
I'm not sure about portability to other OS's, haven't tried, but .net 5 is planned to be ported to multiple OS's (Search ".net 5 platforms", https://devblogs.microsoft.com/dotnet/introducing-net-5/ ) - so this technology is also future proof.
If you don't need the UI or expect the program to run in a CLI, you could parse the filepath as an argument. This would allow you to use the autocomplete feature of your CLI to quickly find the file you need.
This would probably only be handy if the script is non-interactive besides the filepath input.
Another os-agnostic option, use pywebview:
import webview
def webview_file_dialog():
file = None
def open_file_dialog(w):
nonlocal file
try:
file = w.create_file_dialog(webview.OPEN_DIALOG)[0]
except TypeError:
pass # user exited file dialog without picking
finally:
w.destroy()
window = webview.create_window("", hidden=True)
webview.start(open_file_dialog, window)
# file will either be a string or None
return file
print(webview_file_dialog())
Environment: python3.8.6 on Mac - though I've used pywebview on windows 10 before.
I just stumbled on this little trick for Windows only: run powershell.exe from subprocess.
import subprocess
sys_const = ssfDESKTOP # Starts at the top level
# sys_const = 0x2a # Correct value for "Program Files (0x86)" folder
powershell_browse = "(new-object -COM 'Shell.Application')."
powershell_browse += "BrowseForFolder(0,'window title here',0,sys_const).self.path"
ret = subprocess.run(["powershell.exe",powershell_browse], stdout=subprocess.PIPE)
print(ret.stdout.decode())
Note the optional use of system folder constants. (There's an obscure typo in shldisp.h that the "Program Files (0x86)" constant was assigned wrong. I added a comment with the correct value. Took me a bit to figure that one out.)
More info below:
System folder constants