Whenever I add file reading to a python tkinter gui like the code below, the program won't execute when I drag and drop the .py file into python.exe or pythonw.exe. I'm in Windows XP, using Python 3.2.
from tkinter import *
if __name__ == '__main__':
root = Tk()
f = open('hello.txt', 'r')
t = f.read()
f.close()
w = Label(root, text=t)
w.pack()
root.mainloop()
I found that it will work if I set pythonw.exe as the default program for .py files then double click the file, or call it in cmd, but I really need to execute it with drag and drop. Is this a known bug? Thanks in advance!
Related
I have prepared some tk application. It could be really simple like:
from tkinter import *
# create root window
root = Tk()
# root window title and dimension
root.title("Welcome to GeekForGeeks")
# Set geometry (widthxheight)
root.geometry('350x200')
# all widgets will be here
# Execute Tkinter
root.mainloop()
I have using some method to convert the app to the exe file.
What is important,
I'm not using and I cannot do it with pyinstaller py2exe etc. I also cannot use method with changing my app.py to app.pyw.
But my conversion to .exe is working correctly.
The question - is it even possible to hide/disable/resize(reduce the size) of my console window and make the application still working?
I'm not exactly sure how is it done in pyinstaller py2exe etc, so maybe is it possible to do it inside an application?
All right, to solve above problem install:
pip install pywin32
and add code before running your tk gui application:
import win32gui
import win32.lib.win32con as win32con
the_program_to_hide = win32gui.GetForegroundWindow()
win32gui.ShowWindow(the_program_to_hide , win32con.SW_HIDE)
Then you can run the main.py in console, the console will disappear and the gui app will be still visible.
In case when you use pyinstaller etc - you can convert the application without "--noconsole" argument.
When you run the .exe file the console will appear for a second, and disappear. But the gui app will be still visible and usable.
Hope it help somebody somehow :)
I think you should run your script using pythonw.exe instead of python.exe. See .pyw files in python program
Does this help if using Toplevel?
from tkinter import *
root = Tk()
root.title("Main Window")
root.geometry("200x200")
def launch():
global second
second = Toplevel()
second.title("Child Window")
second.geometry("400x400")
def show():
second.deiconify()
def hide():
second.withdraw()
Button(root, text="launch Window", command=launch).pack(pady=10)
Button(root, text="Show", command=show).pack(pady=10)
Button(root, text="Hide", command=hide).pack(pady=10)
root.mainloop()
For example:- first the program should lock abc.exe file and the file should only be able to unlock or run when user enters the correct password for it.
This should happen using Python program, since this is just a submodule of a main program.
This program do locks the program but unlocking doesn't work.
'''
import locket
from tkinter import *
from tkinter import ttk
win = Tk()
win.title('SELECT THE PROGRAM')
path = "C:\\users\\admin\\abc\\abc.exe"
lock = locket.lock_file(path)
try:
lock.acquire()
finally:
lock.release()
#locket._unlock_file()
def close_win():
win.destroy()
def disable_event():
pass
btn = ttk.Button(win, text="Click here to Close", command=close_win)
btn.pack()
win.protocol("WM_DELETE_WINDOW", disable_event)
# Create a fullscreen window
win.attributes('-fullscreen', True)
win.mainloop()
'''
I played with your idea and "unlocking doesn't work" because the file is empty. When you try to lock the file the original file get 0 bytes and is not "unlocking" because windows can not run an empty executable file.
Try this for your self: Create an empty text file with any name and replace the extension of the file from txt to exe and try to run it. You will get same error message from windows.
In my case is look like this:
Now an work around for this is to move your original file some where in PC and rename it to something else with a different extension just to hide it from users and instead of the original file place a fake one with same name. After you get the user condition of using the file you can move it back. Roaming is most common directory for software's to save some extra files and is locket-ed under "C:\Users\USERNAME\AppData\Roaming"
I will not provide you the source code for this, instead I will let you to think on your own logic. As an hint you will need to search for os library for moving the files under a different name and file handeling.
I am trying to write a Bash script so that I can run my program on a double click. The program uses tkinter and the GUI is the only thing I need to see. My bat file is the following:
python BudgetGUI.py &
This runs the code and successfully prints any print statements I have throughout my code but it never opens up the GUI. It simply runs through and closes immediately.
How can I modify the bash script to run the GUI?
Thanks in advance!
Edit Solutions for both mac and pc would be great, though at the moment I am on PC. I am working in Python3.
You need to add a call to mainloop(). I can't say for sure without seeing your code, but probably you need to add root.mainloop() to the bottom.
You don't need a bash or bat file. For your mac, just add a shebang and make the file executable. For Windows, add a shebang and associate the file with py.exe.
If you want to suppress the command line from popping up along with the GUI, rename your file with a .pyw extension.
Make the window made with tkinter stay out of IDLE*
if you have
root = Tk()
at the end put
root.mainloop()
if you have another name for that like:
window1 = Tk()
then, at the end put
window1.mainloop()
and so for any name you gave to the istance of Tk()
A little example
import tkinter as tk
class Window:
root = tk.Tk()
label = tk.Label(root, text = "Ciao").pack()
app = Window()
app.root.mainloop()
Python 2
The code above is for python 3.
For python 2 you just need to change the first line (Tkinter with T, not t)
import Tkinter as tk
[1]
The code is:
import Tkinter
from Tkinter import *
# Create Tk instance
root = Tkinter.Tk(className="test")
# Open Notepad
def openNotepad():
import pywinauto
app = pywinauto.Application.start("notepad.exe")
# Add menu
menu = Menu(root)
root.config(menu=menu)
filemenu = Menu(menu)
menu.add_cascade(label="01 File", menu=filemenu)
filemenu.add_command(label="New", command=openNotepad)
# Pack all
root.mainloop()
[2]
The code works if I double click on .py file.
If I leave only the openNotepad() function, then .exe will work.
According to docs: https://github.com/pyinstaller/pyinstaller/wiki/Supported-Packages, the pywinauto library is supported.
If I leave only the Tkinter snippet, the .exe will work.
Therefore please share what I am doing wrong or please suggest other python installer for python 2.7x.
By commenting out the line starting with: excludedimports in files \PyInstaller\hooks\hook-PIL.py and hook-PIL.SpiderImagePlugin.py, the problem was solved.
Try to replace every exit(), quit(), or os._exit() with sys.exit().
I see that you don't have any of these in your code but somebody else might find this advice to be useful.
My versions: python3.4, pyinstaller3.1.1
I'm using OS X. I'm double clicking my script to run it from Finder. This script imports and runs the function below.
I'd like the script to present a Tkinter open file dialog and return a list of files selected.
Here's what I have so far:
def open_files(starting_dir):
"""Returns list of filenames+paths given starting dir"""
import Tkinter
import tkFileDialog
root = Tkinter.Tk()
root.withdraw() # Hide root window
filenames = tkFileDialog.askopenfilenames(parent=root,initialdir=starting_dir)
return list(filenames)
I double click the script, terminal opens, the Tkinter file dialog opens. The problem is that the file dialog is behind the terminal.
Is there a way to suppress the terminal or ensure the file dialog ends up on top?
Thanks,
Wes
For anybody that ends up here via Google (like I did), here is a hack I've devised that works in both Windows and Ubuntu. In my case, I actually still need the terminal, but just want the dialog to be on top when displayed.
# Make a top-level instance and hide since it is ugly and big.
root = Tkinter.Tk()
root.withdraw()
# Make it almost invisible - no decorations, 0 size, top left corner.
root.overrideredirect(True)
root.geometry('0x0+0+0')
# Show window again and lift it to top so it can get focus,
# otherwise dialogs will end up behind the terminal.
root.deiconify()
root.lift()
root.focus_force()
filenames = tkFileDialog.askopenfilenames(parent=root) # Or some other dialog
# Get rid of the top-level instance once to make it actually invisible.
root.destroy()
Use AppleEvents to give focus to Python. Eg:
import os
os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')
I had this issue with the window behind Spyder:
root = tk.Tk()
root.overrideredirect(True)
root.geometry('0x0+0+0')
root.focus_force()
FT = [("%s files" % ftype, "*.%s" % ftype), ('All Files', '*.*')]
ttl = 'Select File'
File = filedialog.askopenfilename(parent=root, title=ttl, filetypes=FT)
root.withdraw()
filenames = tkFileDialog.askopenfilenames(parent=root,initialdir=starting_dir)
Well parent=root is enough for making tkFileDialog on top. It simply means that your root is not on top, try making root on top and automatically tkFileDialog will take top of the parent.
None of the other answers above worked for me 100% of the time.
In the end, what worked for me was adding 2 attibutes: -alpha and -topmost
This will force the window to be always on top, which was what I wanted.
import tkinter as tk
root = tk.Tk()
# Hide the window
root.attributes('-alpha', 0.0)
# Always have it on top
root.attributes('-topmost', True)
file_name = tk.filedialog.askopenfilename( parent=root,
title='Open file',
initialdir=starting_dir,
filetypes=[("text files", "*.txt")])
# Destroy the window when the file dialog is finished
root.destroy()
Try the focus_set method. For more, see the Dialog Windows page in PythonWare's An Introduction to Tkinter.