Command in the button executes without showing the button widget.(Python tkinter) - python

(Attempt 1): Command in the button executes without showing the button widget. (I would like the user click browse button to select the file)
(Attempt 2): If I use lambda then the next chunk of code immediately after the button gets executed throwing error. As the merge_doc = MailMerge(file_name) gets its file_name only after the button command gets executed. Please suggest.
Attempt 1
from tkinter import *
from tkinter import ttk
from mailmerge import MailMerge
import tkinter as tk
import os
from tkinter import filedialog
import tkinter.font as font
root = tk.Tk()
root.geometry("")
root.title("Test")
file_name=""
def main():
global file_name
file = filedialog.askopenfile(initialdir="./")
if file:
file_name=file.name
browse_button = Button(root, text ='BROWSE',command=main())
browse_button.grid(row=1, column=0, padx=10, ipadx=25,ipady=35)
browse_button.grid_forget()
merge_doc = MailMerge(file_name)
Attempt 2
from tkinter import *
from tkinter import ttk
from mailmerge import MailMerge
import tkinter as tk
import os
from tkinter import filedialog
import tkinter.font as font
root = tk.Tk()
root.geometry("")
root.title("Test")
file_name=""
def main():
global file_name
file = filedialog.askopenfile(initialdir="./")
if file:
file_name=file.name
browse_button = Button(root, text ='BROWSE',command=lambda:main())
browse_button.grid(row=1, column=0, padx=10, ipadx=25,ipady=35)
browse_button.grid_forget()
merge_doc = MailMerge(file_name)
Error thrown during Attempt 2:
Traceback (most recent call last):
File "C:\Users\Rocky\Desktop\TEST\Testnew.py", line 30, in <module>
merge_doc = MailMerge(file_name)
File "C:\Python38\lib\site-packages\mailmerge.py", line 25, in __init__
self.zip = ZipFile(file)
File "C:\Python38\lib\zipfile.py", line 1251, in __init__
self.fp = io.open(file, filemode)
FileNotFoundError: [Errno 2] No such file or directory: ''

If you want user to click the BROWSE button to select file, then you can use wait_variable():
import tkinter as tk
from tkinter import filedialog
from mailmerge import MailMerge
root = tk.Tk()
filename = tk.StringVar()
def main():
file = filedialog.askopenfilename(initialdir='./')
filename.set(file)
browse_button = tk.Button(root, text='BROWSE', command=main)
browse_button.grid(row=1, column=0, padx=10, ipadx=25, ipady=35)
root.wait_variable(filename) # wait for filename to be updated
browse_button.grid_forget()
# should cater empty filename (user click Cancel in file dialog)
merge_doc = MailMerge(filename.get())
...
Note that you need to cater when user click Cancel button in the file selection dialog.

According to your 1st attempt, you make a button and grid it as:
browse_button = Button(root, text ='BROWSE',command=main())
browse_button.grid(row=1, column=0, padx=10, ipadx=25,ipady=35)
But then you call grid_forget() function which is vanishing the button from tkinter window.
browse_button.grid_forget()
After all, you have to add root.mainloop() to run the window infinitely.
And change
browse_button = Button(root, text ='BROWSE',command=main())
to
browse_button = Button(root, text ='BROWSE',command=main)

On second attempt, put the merge_doc = MailMerge(file_name) statement inside if file: block on main().
Because, when python reads the code, initially the file_name variable contains "". So, before pressing any button, it calls merge_doc = MailMerge(file_name) where file_name is "". So, if you want to call the method after choosing the file, put it inside the if block.

Related

Tkinter getting file path returned to main function to use and pass on to other functions

This is my current code.
from tkinter import *
from tkinter import ttk, filedialog
from tkinter.filedialog import askopenfile
import os
def main():
path = open_file()
print(path)
# Create an instance of tkinter frame
win = Tk()
# Set the geometry of tkinter frame
win.geometry("700x350")
def open_file():
file = filedialog.askopenfile(mode='r', filetypes=[('PDF', '*.pdf')])
if file:
filepath = os.path.abspath(file.name)
quit()
print(filepath)
def quit():
win.destroy()
# Add a Label widget
label = Label(win, text="Click the Button to browse the Files", font=('Georgia 13'))
label.pack(pady=10)
# Create a Button
ttk.Button(win, text="Browse", command=open_file).pack(pady=20)
win.mainloop()
if __name__ == '__main__':
main()
I want to create a simple GUI to select a file and then use its path in other functions later on. In the current code the filepath prints out fine after the window closes in the open_file function, but it only works if the print statement is in the function. If I remove it from there and want to print it out(just to test) or use it further to pass it to other functions from main it doesn't seem to work. There is no error but it doesn't print anything either. Any idea?
The problem appears to be is wanting to return a value from a function called with a button. This is apparently not possible. The easiest solution I've found (without changing too much of your code structure) is to use a global variable for filepath. Now you can use it pretty much anywhere you want.
Also, I've removed path = open_file() from your main() function as it is redundant. The function is now called only when the button is pressed and not at every start of the program.
from tkinter import *
from tkinter import ttk, filedialog
from tkinter.filedialog import askopenfile
import os
def main():
print(filepath)
# Create an instance of tkinter frame
win = Tk()
# Set the geometry of tkinter frame
win.geometry("700x350")
def open_file():
file = filedialog.askopenfile(mode='r', filetypes=[('PDF', '*.pdf')])
if file:
global filepath
filepath = os.path.abspath(file.name)
quit()
def quit():
win.destroy()
# Add a Label widget
label = Label(win, text="Click the Button to browse the Files", font=('Georgia 13')) label.pack(pady=10)
# Create a Button
ttk.Button(win, text="Browse", command=open_file).pack(pady=20)
win.mainloop()
if __name__ == '__main__':
main()

Tkinter window not opening in pycharm

I am eriting code in pycharm with tkinter but the window is not opening. May someone assist?
`
import tkinter
window = tkinter.Tk()
button = tkinter.Button(window, text="Do not press this button! >:-(", width=40)
button.pack(padx=10, pady=10)
`
i tried checking my script for bugs but nothing
This has nothing to do with Pycharm, but with tkinter library and how to use it.
You are missing 2 important stuff:
Button is in ttk.py file inside tkinter library: from tkinter import ttk
Execute the whole script with mainloop
Try this:
import tkinter
from tkinter import ttk # Import ttk file from tkinter library
window = tkinter.Tk()
window.title("Coolest title ever written")
button = ttk.Button(window, text="Do not press this button! >:-(", width=40) # Use Button from the import ttk file
button.pack(padx=10, pady=10)
window.mainloop() # Execute the whole script

Tkinter - Linking buttons to different scripts

I am exploring GUI's at the moment. What I want is to have a GUI with a 2 buttons and I want each of the buttons to run a separate python script when clicked.
I have outlined my code below (the first button runs just fine but I am having issues with the second button.
Error Message when I choose the second button:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\tkinter\__init__.py", line 1883, in __call__
return self.func(*args)
Code:
from tkinter import *
import tkinter as tk
master = Tk()
def First_Scriptcallback():
exec(open(r'Desktop\Automation\First_Script.py').read())
def second_Scriptcallback():
exec(open(r'Desktop\Automation\Second_Script.py').read())
#master.title("Test GUI")
#canvas = tk.Canvas(master, height=300, width = 400)
#canvas.pack()
firstButton = Button(master, text="Run first script", command=First_Scriptcallback)
firstButton.pack()
secondButton = Button(master, text="Run second script", command=second_Scriptcallback)
secondButton.pack()
mainloop()
Thanks
As #matiiss suggested importing the other scripts into your program can help and it can be done like this,
import First_Script as first
import Second_Script as second
from tkinter import *
import tkinter as tk
master = Tk()
def First_Scriptcallback():
first.function_name()#here you must create functions in first_script to call in this main script
def second_Scriptcallback():
second.function_name()
#master.title("Test GUI")
#canvas = tk.Canvas(master, height=300, width = 400)
#canvas.pack()
firstButton = Button(master, text="Run first script", command=First_Scriptcallback)
#command=first.function_name
#we can also directly call an function using above command,but sometimes there are problems related to this approch
firstButton.pack()
secondButton = Button(master, text="Run second script", command=second_Scriptcallback)
#command=second.function_name
secondButton.pack()
mainloop()
here for this example the scripts and the program must be in same directory.

How to get a user-selected file and feed it to a python program in Tkinter

I am currently messing about with Tkinter creating an interface for a project I created. The program takes in a bunch of file paths as inputs for it to run. I'm trying to create a tkinter interface where I can upload the 4 files I need or at least somehow get the filepaths and the. feed those to the program. Here is what I have:
import sys
import os
import comparatorclass
from tkinter import *
from tkinter.ttk import *
from tkinter.filedialog import askopenfile
root=Tk()
root.geometry('1000x1000')
def open_file():
file = askopenfile(mode ='r', filetypes =[('Python Files', '*.py')])
if file is not None:
content = file.read()
print(content)
def run_comparator():
comparatorclass.main()
button2 = Button(root, text ='Open', command = lambda:open_file())
button2.pack(side = TOP, pady = 10)
button1 = Button(root,text="hello",command= run_comparator)
button1.pack()
root.mainloop()
as you can see, I have two buttons. The issue I'm having is how to connect my openfile function to my run_comparator function such that the 4 files I need to open are passed on to the run_comparator

Is there a way to add a button in an askopenfile dialog window?

So this is the code
from tkinter import *
from tkinter import filedialog
win = Tk()
win.geometry('200x100')
def printer():
print("hello")
In the browse function im creating an askopenfile dialog window that allows me to choose a file with the button "Open"
def browse():
file = filedialog.askopenfile(parent=win, mode='rb', title='Choose a file')
if file is not None:
file.close()
In this browse function i would like an extra button next to the "Open" button that would say "Print" for example and would trigger the printer function from above
browse_button = Button(win, text="Browse", command=browse)
browse_button.pack(pady=100 / 10)
win.mainloop()

Categories

Resources