I want to execute function with one click on listbox. This is my idea:
from Tkinter import *
import Tkinter
def immediately():
print Lb1.curselection()
top = Tk()
Lb1 = Listbox(top)
Lb1.insert(1, "Python")
Lb1.insert(2, "Perl")
Lb1.insert(3, "C")
Lb1.insert(4, "PHP")
Lb1.insert(5, "JSP")
Lb1.insert(6, "Ruby")
Lb1.pack()
Lb1.bind('<Button-1>', lambda event :immediately() )
top.mainloop()
But this function print before execute selecting...You will see what is the problrm when you run this code.
You can bind to the <<ListboxSelect>> event as described in this post: Getting a callback when a Tkinter Listbox selection is changed?
TKinter is somewhat strange in that the information does not seemed to be contained within the event that is sent to the handler. Also note, there is no need to create a lambda that simply invokes your function immediately, the function object can be passed in as shown:
from Tkinter import *
import Tkinter
def immediately(e):
print Lb1.curselection()
top = Tk()
Lb1 = Listbox(top)
Lb1.insert(1, "Python")
Lb1.insert(2, "Perl")
Lb1.insert(3, "C")
Lb1.insert(4, "PHP")
Lb1.insert(5, "JSP")
Lb1.insert(6, "Ruby")
Lb1.pack()
Lb1.bind('<<ListboxSelect>>', immediately)
top.mainloop()
Related
This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed last year.
I wanted to make button in tkinter, but when I started program, the command always calls when code just starts.
Here is example code:
import tkinter as tk
from tkinter import messagebox
window = tk.Tk()
window.title("Why this don't works???")
window.wm_geometry("100x100")
def message():
messagebox.showinfo("Hi there")
button = tk.Button(text="Hello", command=message())
button.grid(column=0, row=0)
while True:
window.update()
And then, button didn't worked. (When you press it, it don't works.)
I don't know what I'm doing wrong, so I need help.
The command should be a pointer to a function
In the code you wrote, the command gets the return value from the function.
command=message()
The correct way is
command = message
The problem is you are requesting a return value from the fucnction. Try using this.
from tkinter import *
# import messagebox from tkinter module
import tkinter.messagebox
# create a tkinter root window
root = tkinter.Tk()
# root window title and dimension
root.title("When you press a button the message will pop up")
root.geometry('75x50')
# Create a messagebox showinfo
def onClick():
tkinter.messagebox.showinfo("Hello World!.", "Hi I'm your message")
# Create a Button
button = Button(root, text="Click Me", command=onClick, height=5, width=10)
# Set the position of button on the top of window.
button.pack(side='top')
root.mainloop()
You have 2 errors:
first:
It must be command=message
second:
You must give a message argument too, you entered a title only.
Or, what you can do is.
Add another variable.
command = message()
Before this line,
button = tk.Button(text="Hello", command=message())
And chande this line to,
button = tk.Button(text="Hello", command=command)
I have two files:
functions.py
import tkinter as tk
class funcs():
def func1(entry):
entry.delete(0, tk.END)
main.py
import tkinter as tk
import functions as f
root = tk.Tk()
entrybox = tk.Entry(master=root).grid()
button = tk.Button(master=root, command=f.funcs.func1(entrybox)).grid()
root.mainloop()
In main.py, I have assigned the command func1 with the argument entrybox to the widget button.
My intent is to have the entry argument represent an entry widget I want to manipulate.
This line of code is broken:
button = tk.Button(master=root, command=f.funcs.func1(entrybox)).grid()
The problem is that when I run the program, the function is called immediately and does not get assigned to the button.
I am looking for a way to assign a function with arguments to a button in tkinter.
You can use an anonymous function:
tk.Button(
master=root,
command=lambda: f.funcs.func1(entrybox)
)
Python recognizes the broken line of code as an immediate call, so you have to do lambda:
button = tk.Button(master=root, command=lambda: f.funcs.func1(entrybox)).grid()
and as far as I know that will get rid of the problem.
I am trying to get a Tkinter popup to display when a button is clicked.My issue is that every thing runs just fine except the popup will not produce. I have tried multiple ways to create the popup using tkMessagebox and Toplevel() but still not luck. The program runs but when the button is click nothing happens. I have referenced similar post but still can not find the issue in my code. Any thoughts?
from tkinter import *
def new():
root2 = Tk()
root2.geometry('250x250')
l = Label(root2,text="Please Scan Tag").pack()
root2.mainloop()
# setting main frame
root = Tk()
root.geometry('800x650')
root.title("Pass")
root.configure(background= "white")
label_0 = Label(root, text="Pass",width=10,font=("bold", 50),fg= "green",bg="white")
label_0.place(x=186,y=76)
Button(root,command="new", text='new',font=
("bold",15),width=15,height=4,bg='blue',fg='white').place(x=155,y=300)
root.mainloop()
The command option requires a reference to a callable function, not a string.
Button(root,command=new, ...)
I'm trying to create a dynamically-updating searchbox and instead of polling the the entry widget every x milliseconds, I am trying to use keyboard bindings to get the contents of the entry widget whenever a key on the keyboard is pressed:
from tkinter import *
root = Tk()
def callback():
result = searchbox.get()
print(result)
#do stuff with result here
searchbox = Entry(root)
searchbox.pack()
searchbox.bind("<Key>", lambda event: callback())
root.mainloop()
my problem is that searchbox.get() is always executed before the key the user pressed is added to the searchbox, meaning the result is the content of the searchbox BEFORE the key was pressed and not after.
For example if I were to type 'hello' in the searchbox, I would see the following printed:
>>>
>>> h
>>> he
>>> hel
>>> hell
Thanks in advance.
There's no need to use bindings. You can associate a StringVar with the widget, and put a trace on the StringVar. The trace will call your function whenever the value changes, no matter if it changes from the keyboard or the mouse or anything else.
Here's your code, modified to use a variable with a trace:
from tkinter import *
root = Tk()
def callback(*args):
result = searchbox.get()
print(result)
#do stuff with result here
var = StringVar()
searchbox = Entry(root, textvariable=var)
searchbox.pack()
var.trace("w", callback)
root.mainloop()
For information about the arguments passed to the callback see What are the arguments to Tkinter variable trace method callbacks?
For a better understanding of why your bindings seem to always be one character behind, see the accepted answer to Basic query regarding bindtags in tkinter
im new topython 2.7 and want to know if it is possible to open a tkinter messagebox with a button combination on keyboard (Ctrl+alt+'something')
that pops up like an windows error message
import win32api
import time
import math
import Tkinter
import tkMessageBox
top = Tkinter.Tk()
def Message():
tkMessageBox.showinfo("Window", "Text")
for i in range(9000):
x = int(600+math.sin(math.pi*i/100)*500)
y = int(500+math.cos(i)*100)
win32api.SetCursorPos((x,y))
time.sleep(.01)
Yes, you can bind to control and alt characters. Bindings are fairly well documented. Here's one good source of information:
http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
As an example, to bind to ctrl-alt-x you would do this:
top.bind("<Control-Alt-x>", Message)
You can bind to a sequence of events by specifying the whole sequence. For example, if you wanted to implement a cheat code you could do something like this:
label.bind("<c><h><e><a><t>", Message)
For letters, "a" is the same as "<a>", so you can also do this:
label.bind("cheat", Message)
Here is a complete working example:
import Tkinter as tk
import tkMessageBox
def Message(event=None):
tkMessageBox.showinfo("Window", "Text")
def Cheat(event=None):
tkMessageBox.showinfo("Window", "Cheat Enabled!")
root = tk.Tk()
label = tk.Label(root, text="Press control-alt-m to see the messagebox\ntype 'cheat' to enable cheat.")
label.pack(fill="both", expand=True, padx=10, pady=100)
label.bind("<Control-Alt-x>", Message)
label.bind("<c><h><e><a><t>", Cheat)
label.focus_set()
root.mainloop()
If you want something like: Press button A, then press button B then open a Message box it is possible.
Do something like:
from Tkinter import *
import tkMessageBox
def change():
global switch
switch=True
def new_window():
if switch:
tkMessageBox.showinfo("Random name", "Correct combination")
else:
print "Not the correct order"
root = Tk()
switch = False
root.bind("<A>", change)
root.bind("<B>",new_window)
root.mainloop()
If you want more buttons then use an integer and increase it while using switches for the correct button order.
Note that you can bind key combinations as well with root.bind("<Shift-E>") for example
Edit: Now a and b keyboard button insted of tkinter buttons