I'm trying to get the user input from an entry box and once a button is pressed, display that in a tk.Text(). The reason I am not doing it in a label is because I'd like the gui looking something like this:
User: Hey
Response: What's up
User: Nothing..
I had a look at this documentation :http://effbot.org/tkinterbook/text.htm
And example uses here but can't get mine to work.
result = None
window = Tk()
def Response():
global result
result = myText.get()
#The below print displays result in console, I'd like that in GUI instead.
#print "User: ", result
#Creating the GUI
myText = tk.StringVar()
window.resizable(False, False)
window.title("Chatbot")
window.geometry('400x400')
User_Input = tk.Entry(window, textvariable=myText, width=50).place(x=20, y=350)
subButton = tk.Button(window, text="Send", command=Response).place(x =350, y=350)
displayText = Text(window, height=20, width=40)
displayText.pack()
displayText.configure(state='disabled')
scroll = Scrollbar(window, command=displayText).pack(side=RIGHT)
window.mainloop()
I have tried variations of;
displayText.insert(window,result) and displayText.insert(End, result)
But still get nothing when I submit the text. The key thing is to obviously keep the last stored text of the User, rather than overwriting it, simply displaying each input underneath each other, I have been advised Text is the best method for this.
UPDATE
Thanks to the comments and answer by Kevin, the user text is now showing in the gui, but when I enter something and click send again, it goes to the side, like this:
HeyHey
rather than :
Hey
Hey
My chatbot is linked to Dialogflow and so in between each user input the chatbot will respond.
as jasonharper indicated in the comments, you need to un-disable your text box before you can add text to it. Additionally, displayText.insert(window,result) is not the correct way to call it. insert's first argument should be an index, not the window object.
Try:
def Response():
#no need to use global here
result = myText.get()
displayText.configure(state='normal')
displayText.insert(END, result)
displayText.configure(state='disabled')
(You may need to do tk.END or tkinter.END instead of just END, depending on how you originally imported tkinter. It's hard to tell since you didn't provide that part of your code)
Related
I am new to Tkinter so sorry if the question looks trivial. I developed a selenium application and now I am trying to make it interactive with Tkinter.
I am experiencing some issues to pass text entries as input of a function:
I defined the function to log in, which has been already tested and works properly:
def SelfsignIn(user,passw):
browser = webdriver.Firefox(executable_path='C:\Program Files (x86)\geckodriver.exe') (You can find the entire code at the end)
....
Then I am creating the GUI which should take username and password typed by the user as argument of the SelfsignIn function:
After some reaserch I come up with this method:
window = tk.Tk()
window.title("Login Window")
greeting = tk.Label(text="Welcome")
greeting.pack()
username = tk.Label(text="Username")
username_entry = tk.Entry()
password = tk.Label(text="Password")
password_entry = tk.Entry()
username.pack()
username_entry.pack()
password.pack()
password_entry.pack()
par1 = str(username_entry.get())
par2 = str(password_entry.get())
button = tk.Button(window, text='Log in', width=25,command=lambda: SelfsignIn(par1,par2))
button.pack()
window.mainloop()
The function is called properly, in fact the web page opens and does all operations till when it's time to use the credentials. At this point, the login text boxes are not filled with the input given in the GUI.
What am I doing wrong? Feel free to give me any kind of suggestion, thanks in advance.
You're calling username_entry.get() about a millisecond after creating the entry widget. The user won't have even seen the widget, much less had time to type.
Don't use lambda - call a proper function, and have the function get the data when it is needed and not before. This will make your code easier to write, easier to understand, and easier to maintain.
def signin():
par1 = str(username_entry.get())
par2 = str(password_entry.get())
SelfsignIn(par1, par2)
...
button = tk.Button(window, text='Log in', width=25,command=signin)
Your mistake is, that you take the value of the fields out before the GUI is even displayed, so naturally the two string par1 and par2 will be empty.
You have to get the value inside the entry's when you press the button.
OK, I been using guizero for a couple of days but I found a problem that has been perplexing me. Here a simplified version of the code.
from guizero import App, Text, PushButton, Picture, Drawing, TextBox
app = App("Testing")
def test():
global testing
print(testing)
button = PushButton(app,test, text = "press to test")
button.bg = "red"
button.text_size= 35
tittle = Text(app, "Testing input here")
testing = TextBox(app, text= "" )
app.display()
No matter what the users input into the Textbox, it is always print:
[TextBox] object with text ""
I tried putting testing into an argument in the function test, it comes up with the same thing.
[TextBox] object with text ""
If I don't make an argument in the function or global testing, it makes the same thing, and if I make the textbox before the button, I have the same problem.
Can anyone find a way to work around the problem or to fix this, I'm new to guizero so I have little to an idea what I'm doing
If you want to print the contents of the Text widget then you need to do
def test():
global testing
print(testing.value)
This will get the value of the testing widget rather than the "repr" of the widget.
Seems like a bit of "bug" in guizero that the description text that is output doesn't update when the value of the widget is updated.
Issue has been accepted by the developer and a fix has been pushed to a development branch. https://github.com/lawsie/guizero/issues/392
I have some pretty simple code right now that I am having issues with.
root = Tk()
label1 = Label(root, text ="Enter String:")
userInputString = Entry(root)
label1.pack()
userInputString.pack()
submit = Button(root,text = "Submit", command = root.destroy)
submit.pack(side =BOTTOM)
root.mainloop()
print(userInputString)
When I run the code everything operates as I would expect except
print(userInputString)
for an input asdf in the Entry print will return something like 0.9355325
But it will never be the same value back to back always random.
I am using python 3.5 and Eclipse Neon on a Windows 7 Machine.
Ultimately the goal is to accept a string from the user in the box that pops up and then be able to use that value as string later on. For example, it might be a file path that needs to be modified or opened.
Is Entry not the correct widget I should be using for this? Is there something inherently wrong with the code here? I am new to python and don't have a lot of strong programming experience so I am not even certain that this is set up right to receive a string.
Thanks in advance if anyone has any ideas.
There are two things wrong with your print statement. First, you print the widget, not the text in the widget. print(widget) prints str(widget), which is the tk pathname of the widget. The '.' represents the root window. The integer that follows is a number that tkinter assigned as the name of the widget. In current 3.6, it would instead be 'entry', so you would see ".entry".
Second, you try to print the widget text after you destroy the widget. After root.destroy, the python tkinter wrapper still exists, but the tk widget that it wrapped is gone. The following works on 3.6, Win10.
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text="Enter String:")
entry = tk.Entry(root)
def print_entry(event=None):
print(entry.get())
entry.bind('<Key-Return>', print_entry)
entry.focus_set()
submit = tk.Button(root, text="Submit", command=print_entry)
label.pack()
entry.pack()
submit.pack()
root.mainloop()
Bonus 1: I set the focus to the entry box so one can start typing without tabbing to the box or clicking on it.
Bonus 2: I bound the key to the submit function so one can submit without using the mouse. Note that the command then requires an 'event' parameter, but it must default to None to use it with the button.
The NMT Reference, which I use constantly, is fairly complete and mostly correct.
I have a following peice of code where I want query button to disappear when entry box is empty. But that is not happening.When I tried to print the entry value on pressing any key, it shows the last value, not the current value.
eg. if "Test" is previous value in pin, than on hitting backspace pin.get() shows Test instead of "Tes". I am new to python and Tkinter, so don't know what silly thing I am doing.
def send_button ():
print pin.get()
if pin.get() == "":
print "in if"
query.place_forget()
else:
query.place(relx=0.0, rely=0.75, relwidth=0.2, relheight=0.15)
return TRUE
#Entry box
pin = StringVar()
ent1 = Entry(top, textvariable = pin, validate = 'key', vcmd = send_button)
#Query button
query = Button (top, command = get_temp, text = 'Query')
top.mainloop()
validation happens before the character is inserted in the widget. That's it's whole purpose: to decide if the edit should be allowed or not. It can't make that decision of the text has already been entered (or deleted).
Entry validation has a way to pass in the value of the text before it is entered, after it is entered, what is being inserted or deleted, and several other pieces of information.
See this answer for a comprehensive example:
https://stackoverflow.com/a/4140988/7432
I am trying to create a simple popup text entry for the user in which a user enters a text and hits submit (a button). Upon clicking submit, I want the popup entry box to close off and continue on with the rest of the code. Following is a sample code for display that I borrowed from an old post here:
from Tkinter import *
root = Tk()
nameLabel = Label(root, text="Name")
ent = Entry(root, bd=5)
def getName():
print ent.get()
submit = Button(root, text ="Submit", command = getName)
nameLabel.pack()
ent.pack()
submit.pack(side = BOTTOM)
root.mainloop()
print "Rest of the code goes here"
I don't have much experience with Tkinter so I am not sure where and how exactly to call the appropriate functions for closing the entry box after the user hits 'Submit'. My guess is it would have to be inside the getName() function?
If I understand you correctly, then all you need to do is call the root window's destroy method at the end of the getName function:
def getName():
print ent.get()
root.destroy()
Doing so is equivalent to manually clicking the X button in the corner of the window.
Alternate method:
since there isn't much to your popup you could also eliminate several lines of code in your GUI, save some CPU and get pretty much the same output with this:
submitvariablename=raw_input('Please enter a Name')
same functionality and much faster, cleaner.
Just a thought.