from Tkinter import *
import webbrowser
root = Tk()
frame = Frame(root)
frame.pack()
url = 'http://www.sampleurl.com'
def OpenUrl(url):
webbrowser.open_new(url)
button = Button(frame, text="CLICK", command=OpenUrl(url))
button.pack()
root.mainloop()
My goal is to open a URL when I click the button in the GUI widget. However, I am not sure how to do this.
Python opens two new windows when I run the script without clicking
anything. Additionally, nothing happens when I click the button.
You should use
button = Button(root, text="CLCK", command=lambda aurl=url:OpenUrl(aurl))
this is the correct way of sending a callback when arguments are required.
From here:
A common beginner’s mistake is to call the callback function when
constructing the widget. That is, instead of giving just the
function’s name (e.g. “callback”), the programmer adds parentheses and
argument values to the function:
If you do this, Python will call the callback function before creating
the widget, and pass the function’s return value to Tkinter. Tkinter
then attempts to convert the return value to a string, and tells Tk to
call a function with that name when the button is activated. This is
probably not what you wanted.
For simple cases like this, you can use a lambda expression as a link
between Tkinter and the callback function:
Alternatively, you don't have to pass the URL as an argument of the command. Obviously your OpenUrl method would be stuck opening that one URL in this case, but it would work.
from Tkinter import *
import webbrowser
url = 'http://www.sampleurl.com'
root = Tk()
frame = Frame(root)
frame.pack()
def OpenUrl():
webbrowser.open_new(url)
button = Button(frame, text="CLICK", command=OpenUrl)
button.pack()
root.mainloop()
Related
I am learning how to use the .get() for tkinter, and trying to write this basic GUI that can store, process, and display data depending on a user input.
Now (I am fairly new to this, so I am probably wrong) to my knowledge, I need to use the .get() and store it into a variable for future uses.
Now here are my codes, but when I run the code, it kept saying I did not define my variable in the function I defined.
I wrote in Pycharm, the variable I wrote in the first line of the function just keep turning grey.
Why is this happening, am I missing something important?
Sidenote:
I have done some research and saw some result regarding using the following method:
StringVar()
fstring, f"{}"
but I still can't figure out how that works and how it is affecting my code that Python is not accepting my variable.
Import tkinter as tk
def event():
expEntry = entry.get()
window = tk.Tk()
entry = tk.Entry(window)
button = tk.Button(window,commnad=event())
expEntry = tk.Label(window,text = expEntry)
entry.pack()
button.pack()
expEntry.pack()
window.mainloop()
You should use a StringVar to store the value of the entry when event() is called by button
import tkinter as tk
def event(): # use this function to update the StringVar
entry_content = entry.get()
entry_var.set(entry_content)
window = tk.Tk()
# declare a StringVar to store the value of your Entry and update your Label
entry_var = tk.StringVar(window, 'Default Text')
# use 'textvariable' here to update the label when the bound variable changes
expEntry = tk.Label(window, textvariable=entry_var)
entry = tk.Entry(window)
# there was a typo in 'command' here, FIY
button = tk.Button(window, text='Press me', command=event)
entry.pack()
button.pack()
expEntry.pack()
window.mainloop()
Note: you don't need the () for the command binding, as you're not calling the event function there! You're just telling the button the name of the function it should call.
Easier way to do this. Just added tk.StringVar().
import tkinter as tk
window = tk.Tk()
window.geometry("700x300")
window.title("StringVar Object in Entry Widget")
var =tk.StringVar(window)
def event():
Label2.config(text=var.get())
myEntry = tk.Entry(window, textvariable=var)
myEntry.pack()
myButton = tk.Button(window, text="Submit", command=event)
myButton.pack()
Label2 = tk.Label(window, font="Calibri,10")
Label2.pack()
window.mainloop()
Output before:
Output after:
i've just started learning tkinter for python, and i'm trying to get the button to change its text when it's clicked on.
this seems like a very simple question, but i can't find any answers. the code i'm using at the moment doesn't work - when the window opens, it displays 'clicked!' as a label above the button immediately, before i've clicked on the button.
from tkinter import *
root = Tk()
def click():
label = Label(root, text = 'clicked!')
label.pack()
button = Button(root, text='click me', command = click())
button.pack()
root.mainloop()
To change an existing button's text (or some other option), you can call its config() method and pass it keyword arguments with new values in them. Note that when constructing the Button only pass it the name of the callback function — i.e. don't call it).
from tkinter import *
root = Tk()
def click():
button.config(text='clicked!')
button = Button(root, text='click me', command=click)
button.pack()
root.mainloop()
You're passing command = click() to the Button constructor. This way, Python executes click, then passes its return value to Button. To pass the function itself, remove the parentheses - command = click.
I'm new to python programming, and I have a bit of trouble with the program structure:
When I make my GUI in the main python part then the code works:
import tkinter as tk
root = tk.Tk()
root.overrideredirect(True)
root.geometry("800x480")
def cb_Gebruiker():
btnUser["text"]= "changed"
btnUser = tk.Button(root, text="User",command = cb_Gebruiker)
btnUser.place(x=1,y=1,width="300",height="73")
root.mainloop()
When I make my GUI in a function, the btn variable is local, so this doesn't work
def MakeBtn():
btnUser = tk.Button(root, text="User",command = cb_Gebruiker)
btnUser.place(x=1,y=1,width="300",height="73")
def cb_Gebruiker():
btnUser["text"]= "changed"
MakeBtn()
root.mainloop()
Now I have a program that's rather large and I want my GUI in a separate file, but then I can't access my GUI components...
And I can't seem to be able to find a tutorial on how to structure a program (python has to many possibilities: script, module, object oriented,..)
How do I solve this?
You will need a lambda to delay the call to the command with a parameter.
def MakeBtn():
btnUser = tk.Button(root, text="User", command = lambda: cb_Gebruiker(btnUser))
btnUser.place(x=1, y=1, width="300", height="73")
def cb_Gebruiker(btnUser):
btnUser["text"] = "changed"
MakeBtn()
root.mainloop()
I am using a tkk.Combobox themed widget in Python 3.5.2. I want an action to happen when a value is selected.
In the Python docs, it says:
The combobox widgets generates a <<ComboboxSelected>> virtual event when the user selects an element from the list of values.
Here on the Stack, there are a number of answers (1, 2, etc) that show how to bind the event:
cbox.bind("<<ComboboxSelected>>", function)
However, I can't make it work. Here's a very simple example demonstrating my non-functioning attempt:
import tkinter as tk
from tkinter import ttk
tkwindow = tk.Tk()
cbox = ttk.Combobox(tkwindow, values=[1,2,3], state='readonly')
cbox.grid(column=0, row=0)
cbox.bind("<<ComboboxSelected>>", print("Selected!"))
tkwindow.mainloop()
I get one instance of "Selected!" immediately when I run this code, even without clicking anything. But nothing happens when I actually select something in the combobox.
I'm using IDLE in Windows 7, in case it makes a difference.
What am I missing?
The problem is not with the event <<ComboboxSelected>>, but the fact that bind function requires a callback as second argument.
When you do:
cbox.bind("<<ComboboxSelected>>", print("Selected!"))
you're basically assigning the result of the call to print("Selected!") as callback.
To solve your problem, you can either simply assign a function object to call whenever the event occurs (option 1, which is the advisable one) or use lambda functions (option 2).
Here's the option 1:
import tkinter as tk
from tkinter import ttk
tkwindow = tk.Tk()
cbox = ttk.Combobox(tkwindow, values=[1,2,3], state='readonly')
cbox.grid(column=0, row=0)
def callback(eventObject):
print(eventObject)
cbox.bind("<<ComboboxSelected>>", callback)
tkwindow.mainloop()
Note the absence of () after callback in: cbox.bind("<<ComboboxSelected>>", callback).
Here's option 2:
import tkinter as tk
from tkinter import ttk
tkwindow = tk.Tk()
cbox = ttk.Combobox(tkwindow, values=[1,2,3], state='readonly')
cbox.grid(column=0, row=0)
cbox.bind("<<ComboboxSelected>>", lambda _ : print("Selected!"))
tkwindow.mainloop()
Check what are lambda functions and how to use them!
Check this article to know more about events and bindings:
http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
Thanks you for the posts. I tried *args and it workes with bind and button as well:
import tkinter as tk
from tkinter import ttk
tkwindow = tk.Tk()
cbox = ttk.Combobox(tkwindow, values=[1,2,3], state='readonly')
def callback(*args):
print(eventObject)
cbox.bind("<<ComboboxSelected>>", callback)
btn = ttk.Button(tkwindow, text="Call Callback", command=callback);
tkwindow.mainloop()
Hello Stack community,
As I tried writing a simple google searchbar GUI app, I seem to have created a trade-off between either a clickable GUI button or a working keyboard command.
This depends on passing 'self' into the function called 'google'. Without 'self' the GUI Submit button will work, and the Enter key will raise an error in the console. With 'self' passed into google, the Enter key will work, but the GUI Submit button raises the opposite error. It has to do with the amount of arguments passed into this function 'google'.
Is there a way to make both the submit button and the Enter key work?
In this example the GUI Submit button works, the Enter key will give an error:
#!/usr/bin/env python3
from tkinter import ttk
from tkinter import *
import webbrowser
def google():
url = "https://www.google.nl/#q=" + search.get()
webbrowser.open_new_tab(url)
#GUI
root = Tk()
search = StringVar()
ttk.Entry(root, textvariable=search).grid()
submit = ttk.Button(root, text="Search", command=google).grid()
root.bind("<Return>", google)
root.mainloop()
Add a default for the times that nothing is passed to the function. It doesn't matter what it is since you don't use it.
def google(event=None):
print("google function called")
## url = "https://www.google.nl/#q=" + search.get()
## webbrowser.open_new_tab(url)
#GUI
root = Tk()
search = StringVar()
ttk.Entry(root, textvariable=search).grid()
submit = ttk.Button(root, text="Search", command=google).grid()
root.bind("<Return>", google)
root.mainloop()
The reason it fails is that a Tkinter callback function passes an event argument. So any callback you pass has to have this argument. Adding an argument fixes it for the bind but then breaks it for the submit.
This is because for the submit no argument is passed and your function now requires an argument. So basically what it means is you can't use the same function for both purposes.
One simple way to get round this is to use a lambda in the bind call.
root.bind("<Return>", lambda e: google())