How do I attach a link to a button properly? - python

I'm trying to attach link to a button that will open when clicked.
from Tkinter import *
import webbrowser
class Window(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title("Anonymous Button Box")
self.pack(fill=BOTH, expand=1)
_Button = Button(self, text="Don't Click", command=webbrowser.open("http://example.com", new=2, autoraise="True"))
_Click = Button(self, text="Click")
_Click.place(x=80, y=0)
_Button.place(x=0, y=0)
root = Tk()
root.geometry("300x300")
app = Window(root)
root.mainloop()
When I run this it automatically opens the link before the box itself pops up. How would I write it so the link only runs when the button is pressed?
would I create another function to open the link then command it to use the function when button is pressed?

As a rule of thumb, a button command should call a function that accepts no parameters. By doing this, it becomes easier to write the command, to create the button, and to debug the program.
So, in this case I would create a function named something like open_browser, oron_dont_click_button, or something like that:
def open_browser(self):
webbrowser.open("http://example.com", new=2, autoraise="True")
Then, the button becomes much easier to implement:
_Button = Button(..., command=open_browser, ...)

I wrapped the button command in a lambda function. So my button looks like this:
`_Button = Button(self, text="Don't Click", command=lambda: webbrowser.open("http://example.com", new=2, autoraise="True"))`

Related

Calling filedialog from inside a class Tkinter

I am trying to write an app in tkinter python that allows you to browse and choose a folder. I am using a class for each frame in my app, for example: BrowseFolders frame. In one of my frames I have a button that calls a command that opens filedialog.askdirectory. However, everytime I push the button the app seems to freeze and I have no other option other than closing it.
This is my class (notice the self.selectFolder_button):
class BrowseFolders(tk.Frame):
def __init__(self, container):
super().__init__(container, bg='#232228')
self.path = ''
# big title
pyglet.font.add_file('ARCENA.ttf')
self.Mp3Scanner_label = tk.Label(self, text="MP3 Scanner", font=('AR CENA', 70),
background='#232228', foreground='#E3EEF9')
self.slogan_label = tk.Label(self, text='Upload your files to MongoDB', font=('AR CENA', 30),
background='#232228', foreground='#E3EEF9')
self.selectFolder_button = tk.Button(self, text="Select Folder", font=('AR CENA', 15),
background='grey', command=self.select_folder)
self.pack()
def select_folder(self):
self.path = filedialog.askdirectory(initialdir='/', title="Select Folder")
def pack(self):
self.Mp3Scanner_label.place(relx=0.5, rely=0.35, anchor='center')
self.slogan_label.place(relx=0.5, rely=0.55, anchor='center')
self.selectFolder_button.place(relx=0.5, rely=0.85, relwidth=0.9, relheight=0.08, anchor='center')
super().pack(expand=True, fill='both')
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title('MP3 Scanner')
self.geometry('600x450')
if __name__ == "__main__":
app = App()
BrowseFolders(app)
app.mainloop()
I've already tried using lambda, changing my select_folder() method to be static, writing the method outside my class. Anything I do where the button somehow calls this function freezes my app. The only case where this does work is when my frame isn't a class.
Thank you very much!
The problem really was the font, I removed pyglet.font.add_file('ARCENA.ttf') and now its working!

tkinter definition with click button

I try to let one of my definitions click a button of my GUI to run another definition:
def1():
#### I don't know the code here
def2():
print("Hello World")
window = Tk()
button1 = Button(window, text="click 2nd button", command = lambda: threading.Thread(target=def1).start())
button2 = Button(window, text="2nd button", command = lambda: threading.Thread(target=def2).start())
This is just a simple example, I can't run def2() directly in def1(), because the first and the second definitions take much time and I use threading to let both definitions run simultaneously.
I need something like click(button2) in def1().

Close button tkinter after pressing button?

I created a button that works perfectly (not entire code here) but I want that once you press the 'Save' button, the window disappear. Someone knows how to do it?
root2 = tk.Tk()
root2.geometry('200x100')
save_button = tk.Button(root2)
save_button.configure(text='Save', command=lambda: ask_parameter(ents1))
save_button.pack()
root2.mainloop()
Based on the extremely limited snippet of code in your question: I would suggest it doing by defining a function to call that does something like this:
import tkinter as tk
def ask_and_close(root, ents):
ask_parameter(ents)
root.destroy()
ents1 = "something"
root2 = tk.Tk()
root2.geometry('200x100')
save_button = tk.Button(root2)
save_button.configure(text='Save', command=lambda: ask_and_close(root2, ents1))
save_button.pack()
root2.mainloop()
Note: If you're creating multiple windows, I wouild suggest using tk.Toplevel() instead of calling tk.TK() more than once.
Just use the master.quit() method!
Example Code:
from tkinter import *
class Test:
def __init__(self):
self.master = Tk()
self.button = Button(self.master, text="Push me!", command=self.closeScreen)
self.button.pack()
def closeScreen(self):
# In your case, you need "root2.quit"
self.master.quit()
test = Test()
mainloop()
I would suggest using destroy() method as used here https://docs.python.org/3.8/library/tkinter.html#a-simple-hello-world-program.
One of the easy ways to invoke the destroy method in your code is this;
def ask_parameter_and_destroy(ents1):
ask_parameter(ents1)
root2.destroy()
root2 = tk.Tk()
root2.geometry('200x100')
save_button = tk.Button(root2)
save_button.configure(text='Save', command=lambda: ask_parameter_and_destroy(ents1))
save_button.pack()
root2.mainloop()
You can read about differences between destroy() and previously proposed quit() methods on the following page: What is the difference between root.destroy() and root.quit()?.
If your goal is to create a dialog for saving a file, you might be interested in tkinter.filedialog library, which has ready made dialog boxes for handling file saving.

tkinter Toplevel window appears not to react to some methods

I have code for selecting backup that should be loaded. It opens Toplevel window and lets you select one of the backups to load. When this window opens, I would like to block input to original window, so the only way to get back to original window is by closing the new Toplevel window.
The part of code that I hoped would work:
from tkinter import *
class BackupsGui:
def __init__(self, parent):
top = Toplevel()
self.top = top
Some more code and __init__ ending with:
top.update_idletasks()
top.overrideredirect(True)
top.mainloop()
or:
top.transient(parent)
top.mainloop()
Niether code part appears to change Toplevel interaction in any way, nor does changing if top.mainloop() precedes top.transient() or top.update_idletasks().
What do I miss?
transient and overrideredirect have nothing to do with event handling. If you want to block all input except for the toplevel, you need to call grab_set on the toplevel window. This will cause all events to be sent to that window.
Run the following code, and notice that if you don't check the box, you can continue to create new windows and change the value of the checkbox. Once checked, the next window grabs all events, preventing you from interacting with the other windows.
import Tkinter as tk
class Example(tk.Frame):
def __init__(self, root):
tk.Frame.__init__(self, root)
self.do_grab = tk.BooleanVar()
cb = tk.Checkbutton(self, text="New window grabs all events",
variable=self.do_grab, onvalue=True, offvalue=False)
cb.pack()
new_button = tk.Button(self, text="New window", command=self.on_click)
new_button.pack()
def on_click(self):
self.top = tk.Toplevel(self)
button = tk.Button(self.top, text="dismiss", command=self.top.destroy)
do_grab = self.do_grab.get()
if do_grab:
label = tk.Label(self.top, wraplength=200,
text="This window grabs all events")
else:
label = tk.Label(self.top, wraplength = 200,
text="This window does NOT grab all events")
label.pack(fill="x")
button.pack()
if do_grab:
self.top.grab_set()
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(side="top", fill="both", expand=True)
root.mainloop()

Tkinter Quit button make exe not responding

I create a window with Tkinter. When I click the quit button, windows shows the exe stop working. Could any one tell me why this happens? I think the problem is the self.quit, but I do not know the reason.
Here is the codes.
from Tkinter import *
class App(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.pack()
self.createWidgets()
def createWidgets(self):
self.Quit = Button(self, text = "QUIT", command = self.quit)
self.Quit.pack(side = LEFT)
root = Tk()
app =App(master = root)
app.mainloop()
In the quit button, you are calling the quit() method of Frame. In its place, you need to call destroy() on the root element to finish the mainloop correctly.
self.Quit = Button(self, text = "QUIT", command = self.master.destroy)

Categories