Python chat box whith Tkinter - python

I'm trying to do a chat box with Tkinter, but for send the text I want to press on Return key and not to click on a button. When Ï run this code, I can wrote in the Entry section, but when I press the Return key, nothing append. Thanks for your help.
(Sorry for bad English)
from tkinter import *
window = Tk()
input_user = StringVar()
input_field = Entry(window, text=input_user)
input_field.pack()
def Enter_pressed(event):
"""Took the current string in the Entry field."""
input_get = input_field.get()
print(input_get)
frame = Frame(window, width=100, height=100)
frame.bind("<Return>", Enter_pressed)
frame.pack()
window.mainloop()

you are binding to the wrong widget, when you press the return key that event is sent to the entry widget not the frame, so change
frame.bind("<Return>", Enter_pressed)
to:
input_field.bind("<Return>", Enter_pressed)
and if you want to prevent other bindings from firing you can add
return "break"
to the end of your function

Related

simple tkinter question - button command (display other text on click)

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.

How to close other window by python Tkinter?

I have following python code in Tkinter.
import tkinter as tk
def main_gui(login, s):
login.quit() # close login window
win = tk.Tk()
win.geometry('300x150')
name = tk.Label(win, text='Hello' + s.get()) # Hello David
name.pack()
win.mainloop()
# initial Tkinter frame
login = tk.Tk()
login.title('Login')
login.geometry('300x150')
# input user name
user_name_var = tk.StringVar()
user_name_var.set('David')
tk.Label(login, text='User name').place(x=10, y=50)
user_name = tk.Entry(login, textvariable=user_name_var)
user_name.place(x=100, y=50)
input_ok = tk.Button(win_login, command=lambda: main_gui(login, user_name), text='OK', width=15)
input_ok.place(x=100, y=90)
win_login.mainloop()
I want to close login window, but my code can not close it. How to solve it.
You are almost there - only two details you have to adapt:
The method to remove a widget in Tkinter is destroy, so login.quit() should be login.destroy().
Once login is destroyed, the user_name Entry will also be destroyed, and you will not be able to get the name from it anymore. You should get the name earlier, e.g., directly in the lambda:
... lambda: main_gui(login, user_name.get()), ...
you can use the
root.withdraw()
function, this will close the window without completely destroying all of the root.after functions

Tkinter Button Function Control by MessageBox

The code below shows part of my program and the issue im facing.
def checkAnswer():
mainAnswer = answer01.get()
if len(mainAnswer) == 0:
messagebox.showwarning(message='Please answer the question!')
return
if int(mainAnswer) != answer:
messagebox.showwarning(message='Incorrect! The correct answer is: ' + str(answer))
else:
nxtquest.config(state=NORMAL)
messagebox.showinfo(message='Correct! :)')question01 = Label(easy)
question01.grid(row=2, column=0)
answer01 = Entry(easy)
answer01.grid(row=3, column=2)
answer01.bind('<Return>', func=lambda e:checkAnswer())
start = Button(easy, text = "Start!", command=ask, bg='green', fg='white')
start.grid(row=3, column=3)
nxtquest = Button(easy, text='Next Question', command=ask)
nxtquest.grid(row=5, column=2)
checkbut = Button(easy, text='Check', command=checkAnswer)
checkbut.grid(row=4, column=2)
#check button and answer01 enabled after start pressed
launch = 1
if launch == 1:
answer01.config(state=DISABLED)
checkbut.config(state=DISABLED)
nxtquest.config(state=DISABLED)
The issue which im struggling here is that whenever i run the program everything is okay. When the window is displayed checkbut, nxtquest and label answer01 are greyed out (disabled).
The start button enables only checkbut and answer01 and then is destroyed. (So far so good)
So nxtquest will enable once the input is correct as seen in the
else:
nxtquest.config(state=NORMAL)
But when I reach another question the nxtquest button is already enabled, this is the problem!
How could I make it so the button will enable itself only after the warning message box is displayed?
Could I ask for some help with this and possibly suggestions if you see any rookie mistakes ?
Whilst I don't know of any way you could do this with a messagebox widget (although I'm sure there's an event you could use as the trigger) you can most certainly do this by substituting the messagebox with a Toplevel widget and using .protocol("WM_DELETE_WINDOW", callback()) on the widget.
This would mean that whenever the Toplevel widget was "closed" we would actually be overwriting the action taken when the event was raised and would manually handle the closing of the widget as well as whatever else we wanted it to do.
This would look something like the below:
from tkinter import *
root = Tk()
button = Button(root, text="Ok", state="disabled")
button.pack()
top = Toplevel(root)
def close():
top.destroy()
button.configure(state="active")
top.protocol("WM_DELETE_WINDOW", close)
root.mainloop()
If you close the Toplevel widget you will see that the button is now active instead. This would equally work if we added a Button to the Toplevel widget which called the function close().

Python 2.7 Tkinter: how do I click & release on two widgets and get responses from both?

I hope you can help me with a problem I have in python 2.7. I couldn't find a solution online, but I'm honestly unsure what keywords to search for, so I'm sorry if this is redundant.
The code below is an example of my problem.
import Tkinter as tk
root = tk.Tk()
#Widgets.
btn1 = tk.Label(root, text="btn1", bg="gray80")
btn2 = tk.Label(root, text="btn2", bg="gray80")
btn1.pack(side=tk.TOP, fill=tk.X)
btn2.pack(side=tk.TOP, fill=tk.X)
#Widget events.
def onClick1(event):
print "Clicked button 1."
def onRelease1(event):
print "Released button 1."
def onClick2(event):
print "Clicked button 2."
def onRelease2(event):
print "Released button 2."
#Bindings.
btn1.bind("<Button-1>", onClick1, add="+")
btn1.bind("<ButtonRelease-1>", onRelease1, add="+")
btn2.bind("<Button-1>", onClick2, add="+")
btn2.bind("<ButtonRelease-1>", onRelease2, add="+")
root.mainloop()
Whenever I click one button (technically a label) and hold it, the onClick event for it fires, but if I drag the mouse over to the other and release it, I get the same onRelease as the one I clicked, and not the one for the label I have my mouse over currently. This has held me back some time now, and I'd hate to scrap the whole feature in my program I need this for, so any help would be greatly appreciated.
The release event always fires on the same widget that got the press event. Within your handler you can ask tkinter what widget is under the cursor.
Example:
import Tkinter as tk
root = tk.Tk()
btn1 = tk.Label(root, text="btn1", bg="gray80")
btn2 = tk.Label(root, text="btn2", bg="gray80")
btn1.pack(side=tk.TOP, fill=tk.X)
btn2.pack(side=tk.TOP, fill=tk.X)
def onRelease(event):
x,y = event.widget.winfo_pointerxy()
widget = event.widget.winfo_containing(x, y)
print("widget:", widget.cget("text"))
btn1.bind("<ButtonRelease-1>", onRelease)
btn2.bind("<ButtonRelease-1>", onRelease)
root.mainloop()

How can the response of a Button go to an Entry in Tkinter

I'm trying to generate the output of each Button click to an Entry, each time I press generate button the output shows up in the console, but I want it to show in the GUI so I tried to add the command command=gen to the Entry and it gives me an error, it seems like Entry's don't accept the argument command, but I'm not too sure if it's just a syntax error, is there another way of displaying the output of the Button click on the Gui? The reason why I wanted it to be an Entry is because it provides a perfect rectangular shape with white inside the box which is perfect for generating things.
from Tkinter import *
def gen():
print ("testetstesttesttest")
window = Tk()
window.geometry("500x300")
window.title("TestGUI")
botton = Button(window, text="Generate ids",command=gen).place(x=210,y=160)
textbox = Entry(window, command=gen).place(x=210,y=100)
window.mainloop()
The error I receive:
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: unknown option "-command"
You want to set the text of the entry directly. As shown in this answer, a StringVar is one way to go about this.
entryText = StringVar(window)
Then, in the your command:
def gen():
entryText.set("testtesttesttest")
Putting it all together:
from Tkinter import *
def gen():
entryText.set("testtesttesttest")
window = Tk()
window.geometry("500x300")
window.title("TestGUI")
entryText = StringVar(window)
botton = Button(window, text="Generate ids",command=gen).place(x=210,y=160)
textbox = Entry(window, textvariable = entryText).place(x=210,y=100)
window.mainloop()

Categories

Resources