简体   繁体   中英

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM