Bash script to run Python Tkinter GUI - python

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

Related

Python tk - hide console window

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()

Tkinter: how to open a Toplevel window from another script

I'm a newbie in programming and I'm struggling a bit (a lot actually) with my first "program". Here's what I did:
since I want the code not to be too long, I want to split it in two files. In the first one I call the main window, where I put a button. If I click this button, I run the second script, that should hide the main window and make appear a new window (toplevel). The problem is that if I click the button nothing happens.
A thing I noticed is that if in the second script I add the strings "if name=="main": main.mainloop()", then this new window does appear, but a second main window appears too, as if I re-runned the main code.
Script one:
from tkinter import *
import os
main=Tk()
def sw():
os.system("python3 ./script_two.py")
my_button=Button(main,text="NEW",command=sw)
my_button.grid(row=0,column=0)
if__name__="__main__":
main.mainloop()
Script two:
from tkinter import *
import os
import script_one
script_one.main.withdraw()
second_window=Toplevel()
def Close():
second_window.destroy()
script_one.main.deiconify()
second_button = Button(second_window,text="Exit",command=Close)
second_button.grid(row=0,column=0)
If I put together the scripts (inserting the code of "script_two" in 'def sw()'), I get exactly what I want, but if I split them as showed, I get the problem.
Obviously for a code this short it would be easier and faster to write a single script, what I actually have is a longer code, but the problem is the same.
Any idea? Thank you very much

Is possible to have the console active only on certain times after compiling the py to exe using pyinstaller or anything else?

I’m building a program in python that will copy large files using robocopy. Since the gui freezes while the copy is done i only have two options:
1. Learn how to do multithreading and design the gui to show the progress and not freeze.
2. Keep the console on after compiling with pyinstaller as an alternative to show robocopy progress while the gui freezes.
I am open to doing multithreading but i’m a beginner and is pretty hard to understand how to make another subprocess for robocopy and from there extract the progress into a label from gui. The option i thought about is to have the cmd console active only while the copy is done. Is it possible? The scenario will be like this:
Open the program (the console will be hidden)
Press the copy button (console pops up and shows the copy progress while the gui freezes)
After the copy is done hide the console again
As i said above. I’m not totally excluding adding multithreading but for that i will need some help.
Thanks!
Please try this code, should be working, please let me know if something wrong:
import tkinter as tk
import os
import subprocess
import threading
main = tk.Tk()
main.title('Title')
frame_main = tk.Frame(main)
frame_main.grid(columnspan=1)
src = 'D:/path/to/the/folder'
dest = 'D:/path/to/the/folder2'
selection_platf = len(os.name)
def copy_build_button():
if selection_platf < 11:
subprocess.call(["robocopy", src, dest, r"/XF", 'BT V_SyncPackage.zip', "/S"])
else: #for linux
subprocess.call(["robocopy", src, dest, "/S"])
def copy_thread():
thread_1 = threading.Thread(target=copy_build_button)
thread_1.start()
button_main1 = tk.Button(frame_main, text="copy_build_button", width=50, height=5, fg="green", command=copy_thread)
button_main1.grid(column=0, sticky='N'+'S'+'E'+'W')
main.mainloop()

python --> pyinstaller - .exe file will return "test returned -1"

[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

tkinter file I/O breaks pythonw.exe drag and drop

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!

Categories