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)
Related
I'm building a tkinter app and as a part of it the user has to upload a file, write a message and then press a Button whose command runs in another thread.
self.sidebar_button = Button(self.sidebar_frame, text="send your message",
command=threading.Thread(target=send_msg).start)
If the Button is pressed in the right condition then everything is fine.
However, if the user doesn't upload the file and write the message before pressing the Button then i show the user an error message. The problem here is that since the first Button press has started the thread, it can't start again.
Can you think of a workaround for this problem?
Is it possible to disable the Button before the right conditions are met?
Look at this:
import tkinter as tk
# This is called each time there is a change in the entry
def check_conditions(*args):
message_text = message_var.get()
# Here we check the conditions:
if message_text == "":
button.config(state="disabled")
else:
button.config(state="normal")
def send():
message_text = message_var.get()
print(f"Send: {message_text!r}")
root = tk.Tk()
message_var = tk.StringVar(root)
# When the value of the `message_var` has changed, call `check_conditions`
message_var.trace("w", check_conditions)
# Create the entry and attach `message_var`
message = tk.Entry(root, textvariable=message_var)
message.pack()
button = tk.Button(root, text="Send", command=send, state="disabled")
button.pack()
root.mainloop()
It uses <tk.StringVar>.trace("w", <function>) to call check_conditions each time the user changes the entry. For more info, read this.
tkinter doesn't always like being called from other threads, so avoid using threading when using tkinter.
The idea of the code is to create N amount of buttons that copy text to the clipboard when pressed, overwriting and saving the text from the last pressed button.
from tkinter import *
import tkinter
r = Tk()
age = '''
O.o
giga
'''
gage = 'vrum'
r.title("getherefast")
def gtc(dtxt):
r.withdraw()
r.clipboard_clear()
r.clipboard_append(dtxt)
r.update()
tkinter.Button(text='age', command=gtc(age)).grid(column=1, row=0)
tkinter.Button(text='gage', command=gtc(gage)).grid(column=2, row=0)
r.mainloop()
With this code I expected to get 2 buttons 'age' and 'gage' and when I press them to get respectively the value saved in the var.
The problem is that the tkinter UI does not load and the Idle window is just standing open.
The result is that I get 'vrum' copied to the clipboard (If age button is the only 1 present I get the correct value but still no GUI from tkinter).
As additional information I'm writing and testing the code in IDLE, Python 3.10.
The problem is that the tkinter UI does not load
Yes it does, but you told it to withdraw(), so you don't see it.
To do this you need a partial or lambda function, you can't use a normal function call in a command argument. Try this:
import tkinter
r = tkinter.Tk()
age = '''
O.o
giga
'''
gage = 'vrum'
r.title("getherefast")
def gtc(dtxt):
r.clipboard_clear()
r.clipboard_append(dtxt)
tkinter.Button(text='age', command=lambda: gtc(age)).grid(column=1, row=0)
tkinter.Button(text='gage', command=lambda: gtc(gage)).grid(column=2, row=0)
r.mainloop()
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, ...)
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 3 years ago.
I'm trying to add a function to each button but when i do, the function opens immediately without me pressing the button in the menu.
Hello, i'm new to programming and i'm trying to learn some basic about creating a menu for a notepad, so far i learned how to create the menu and the buttons inside of it, I'm trying to add a function to each button but when i do, the function opens immediately without me pressing the button in the menu, the only thing that have worked so far is to try the lambda function, but i want to be able to write the function without having to write the whole code for the function after the lambda function.
from tkinter import Tk, scrolledtext, Menu, filedialog
from tkinter.scrolledtext import ScrolledText
from tkinter import*
#Root main window
root = Tk(className=" Text Editor")
textarea = ScrolledText(root, width=80, height=100)
textarea.pack()
# Menu options
menu = Menu(root)
root.config(menu=menu)
filename = Menu(menu)
edicion = Menu(menu)
# Funciones
def open_file ():
file = filedialog.askopenfiles(parent=root, mode='rb', title="Select a file")
if file != None:
contenidos = file.read()
textarea.insert('1.0', contenidos)
file.close
menu.add_cascade(label="File", menu=filename)
filename.add_command(label="New")
filename.add_command(label="Open", command= open_file)
filename.add_command(label="Save")
filename.add_separator()
filename.add_command(label="Exit")
menu.add_cascade(label="Editar", menu=edicion)
edicion.add_command(label="Cortar")
edicion.add_command(label="Pegar")
edicion.add_command(label="Copiar")
textarea.pack()
root.mainloop()
In this line:
filename.add_command(label="Open", command= open_file())
you do not want the extra () after your command, that will call your function. Try without:
filename.add_command(label="Open", command= open_file)
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