I am fairly new to python and am currently working on a school project, my aim is to create a search bar that can be used to search a data file, however I am struggling to get the search bar to work correctly. I am using the tkinter entry widget.
When I call .get(), the string in the entry widget is not printed. Here is my code...
from tkinter import *
def searchButton():
text = searched.get()
print (text)
def drawStatWindow():
global searched
statWindow = Tk()
statWindow.title("View Statistics")
statWindow.config(bg = "grey")
statWindow.geometry('800x900')
searched = StringVar()
searchBox = Entry(statWindow, textvariable = searched)
searchBox.place(x= 450, y=50, width = 200, height = 24)
enterButton = tkinter.Button(statWindow, text ="Enter", command =searchButton)
enterButton.config(height = 1, width = 4)
enterButton.place(x=652, y=50)
drawStatWindow()
When I type a string into the entry widget and press the enter button, nothing happens.
Like I say I am not very experienced and this is my first project, but after reading about the tkinter entry widgets I can't understand why this won't work.
I am using python V3.4.0
Thanks.
Your code lacks a call to mainloop(). You could try adding it to the end of the drawStatWindow() function:
statWindow.mainloop()
You might want to restructure your code into a class. This allows you to avoid using global variables and generally provides better organisation for your application:
from tkinter import *
class App:
def __init__(self, statWindow):
statWindow.title("View Statistics")
statWindow.config(bg = "grey")
statWindow.geometry('800x900')
self.searched = StringVar()
searchBox = Entry(statWindow, textvariable=self.searched)
searchBox.place(x= 450, y=50, width = 200, height = 24)
enterButton = Button(statWindow, text ="Enter", command=self.searchButton)
enterButton.config(height = 1, width = 4)
enterButton.place(x=652, y=50)
def searchButton(self):
text = self.searched.get()
print(text)
root = Tk()
app = App(root)
root.mainloop()
You have to add mainloop() because tkinter needs it to run.
If you run code in IDLE which use tkinter then IDLE runs own mainloop() and code can work but normally you have to add mainloop() at the end.
And you have to remove tkinter in tkinter.Button.
from tkinter import *
def searchButton():
text = searched.get()
print(text)
def drawStatWindow():
global searched
statWindow = Tk()
statWindow.title("View Statistics")
statWindow.config(bg="grey")
statWindow.geometry('800x900')
searched = StringVar()
searchBox = Entry(statWindow, textvariable=searched)
searchBox.place(x= 450, y=50, width=200, height=24)
# remove `tkinter` in `tkinter.Button`
enterButton = Button(statWindow, text="Enter", command=searchButton)
enterButton.config(height=1, width=4)
enterButton.place(x=652, y=50)
# add `mainloop()`
statWindow.mainloop()
drawStatWindow()
No need to use textvariable, you should use this:
searchBox = Entry(statWindow)
searchBox.focus_set()
searchBox.place(x= 450, y=50, width = 200, height = 24)
then you will be able to use searchBox.get(), that will be a string.
Related
I am writing a program "translator". Wrote a programming interface. I want to make it so that I get what the user enters, write to a variable, translate and output.
However I don’t understand how to do it. I have looked at many forums but have not found an answer.
I want the user to enter his text for translation in the left text entry window, I receive this text, write it to a variable, translate and display the translated text in the right window. I want to do this in order to automate the program, so that the translation is automatic, without buttons.
`
from languages import lang
from function import *
from tkinter import *
from tkinter import ttk
import keyboard
from tkinter import messagebox
import googletrans
from googletrans import Translator
root = Tk()
app_width = 800
app_height = 500
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x = (screen_width / 2) - (app_width / 2)
y = (screen_height / 2) - (app_height / 2)
root.title('Переводчик')
root['bg'] = '#1D1B26'
root.geometry(f'{app_width}x{app_height}+{int(x)}+{int(y)}')
root.resizable(width=False, height=False)
style = ttk.Style()
style.configure('TCombobox', pady=15 )
language_selection1 = ttk.Combobox(root, values = lang, font="Comfortaa 10", )
language_selection1.current(1)
language_selection1.place(relx=0.16,y=50)
language_selection1.bind("<FocusIn>", defocus)
exchange_button = PhotoImage(file='transfer.png')
img_label = Label(image=exchange_button)
exchange_button = exchange_button.subsample(18,18)
exchange_button1 = Button(root, image=exchange_button,background='#2ee59d',borderwidth=0, command=exchange_button)
exchange_button1.place(relx=0.49,y=50)
language_selection2 = ttk.Combobox(root, values = lang, font="Comfortaa 10", )
language_selection2.set("Выберите язык")
language_selection2.place(relx=0.66,y=50)
language_selection2.bind("<FocusIn>", defocus)
first_frame = Frame(root, bg="Black")
first_frame.place(x=41, y=100,width= 250, height=200) #127
text1 = Text(first_frame, bg = "White")
text1.place(x=0,y=0,width= 250, height=200)
label2 = Label(root)
second_frame = Frame(root, bg="Black")
second_frame.place(x=528, y=100,width= 250, height=200) #441
text2 = Text(second_frame, bg = "White")
text2.place(x=0,y=0,width= 250, height=200)
root.mainloop()
/function
def defocus(event):
event.widget.master.focus_set()
def exchange_button():
pass
/languages
lang = ['Belarusian',
'English',
'German',
'Italian',
'Japanese',
'Kazakh',
'Kyrgyz',
'Norwegian',
'Polish',
'Russian',
'Spanish',
'Swedish',
'Turkish',
'Ukrainian', ]
`
I want to do this in order to automate the program, so that the translation is automatic, without buttons.
Something has to trigger the translation, but it's not clear what you want that trigger to be. For this answer, I'll assume you want it to happen when the user presses the return key.
First, you need to write a function that does the translation. Since we're going to call this from an event, it needs to take an argument representing the event that triggered the function even though we don't need this argument in the function:
def do_translation(event):
source_lang = language_selection1.get()
target_lang = language_selection2.get()
text = text1.get("1.0", "end").strip()
translated_text = <your code to do the translation>
text2.delete("1.0", "end")
text2.insert("end", translated_text)
Next, instruct tkinter to call this function when the user presses the return key by binding the return key to the function:
text1.bind("<Return>", do_translation)
If you want the translation to happen as the user types, you can bind on the event <Any-KeyRelease> which will cause the function every time the user presses and releases a key:
text1.bind("<Any-KeyRelease>", do_translation)
This question already has answers here:
Tkinter: AttributeError: NoneType object has no attribute <attribute name>
(4 answers)
Closed 2 years ago.
I have a problem with a GUI I created, that includes a label that indicates that the program is working in the background, the real script processes a huge amount of data so I want that indicator to tell the user it is indeed doing something. It worked fine so far like this, displaying "Idle" at script start, "running" while the function runs its course, and "Done" when it's done. (code is only the relevant part):
from tkinter import*
def make_pause_function(sleepytime):
import time
print("Falling asleep")
time.sleep(sleepytime)
print("Awakening")
class MyGUI:
def __init__(self):
self.__mainWindow = Tk()
self.header = StringVar()
self.header.set(3)
self.labelText = 'Idle'
# self.Button2 = Button(text = "Sleep for X seconds!", command = self.run_main_script).grid(row=1,column=0)
# self.Entry2 = Entry(self.__mainWindow, textvariable=self.header, width = 100).grid(row=2,column=0)
# self.Label3 = Label(self.__mainWindow, text = self.labelText).grid(row=3,column=0)
self.Button2 = Button(text = "Sleep for X seconds!", command = self.run_main_script)
self.Entry2 = Entry(self.__mainWindow, textvariable=self.header, width = 100)
self.Label3 = Label(self.__mainWindow, text = self.labelText)
self.Button2.pack()
self.Entry2.pack()
self.Label3.pack()
mainloop()
def run_main_script(self):
self.Label3["text"] = 'running'
self.__mainWindow.update_idletasks()
header=self.header.get()
make_pause_function(int(header))
self.Label3["text"] = 'done'
self.__mainWindow.update_idletasks()
myGUI = MyGUI()
But when the GUI grew because of many options, I switched from pack to grid geometry manager and then the label updating I had gotten working after a lot of trial and error got broken again. The follwing code doesn't work:
from tkinter import*
def make_pause_function(sleepytime):
import time
print("Falling asleep")
time.sleep(sleepytime)
print("Awakening")
class MyGUI:
def __init__(self):
self.__mainWindow = Tk()
self.header = StringVar()
self.header.set(3)
self.labelText = 'Idle'
self.Button2 = Button(text = "Sleep for X seconds!", command = self.run_main_script).grid(row=1,column=0)
self.Entry2 = Entry(self.__mainWindow, textvariable=self.header, width = 100).grid(row=2,column=0)
self.Label3 = Label(self.__mainWindow, text = self.labelText).grid(row=3,column=0)
# self.Button2 = Button(text = "Sleep for X seconds!", command = self.run_main_script)
# self.Entry2 = Entry(self.__mainWindow, textvariable=self.header, width = 100)
# self.Label3 = Label(self.__mainWindow, text = self.labelText)
# self.Button2.pack()
# self.Entry2.pack()
# self.Label3.pack()
mainloop()
def run_main_script(self):
self.Label3["text"] = 'running'
self.__mainWindow.update_idletasks()
header=self.header.get()
make_pause_function(int(header))
self.Label3["text"] = 'done'
self.__mainWindow.update_idletasks()
myGUI = MyGUI()
Seems that update_idletasks doesn't like grid. But I don't like pack for a GUI with lots of buttons and fields. Any way to do what I want with grid packing?
try this:
self.Label3 = Label(self.__mainWindow, text = self.labelText).grid(row=3,column=0)
from that, to this:
self.Label3 = Label(self.__mainWindow, text = self.labelText)
self.Label3.grid(row=3,column=0)
The follwing line causes the error:
self.Label3 = Label(self.__mainWindow, text = self.labelText).grid(row=3,column=0)
grid() is a function that doesn't return anything (None). Because of that, you're saving in variable self.Lable3 nothing. Then, when you run the line self.Label3["text"] = 'running' an error pops up because self.Lable3 is None. In order to solve it, seperate those lines- first save the Label in a variable and then use the grid() function on it:
self.Label3 = Label(self.__mainWindow, text = self.labelText)
self.Label3.grid(row=3,column=0)
By the way, I recommend using place() method instead of grid() because in my opinion it is easier to place objects with it. You can read about it Here
I was trying to create a program inside tkinter that draws different patterns based on user input. I want a 'clear' button on my window that can clear everything on the window. I tried 'turtle.clear" and 'turtle.reset', they work but they open a new turtle window which I dont want and also that I am using tut = turtle.RawTurtle(). What can I do to try to fix this problem?
I use the following sample code:
from tkinter import *
from turtle import *
root = Tk()
tut = None
def reset_button():
tut.reset()
tut.hideturtle()
def draw_again():
tut.speed('fastest')
tut.color('blue', 'yellow')
tut.begin_fill()
while True:
tut.forward(200)
tut.left(170)
if abs(tut.pos()) < 1:
break
tut.end_fill()
button1 = Button(text = 'Reset', command = reset_button)
button1.pack()
button2 = Button(text = 'Draw', command = draw_again)
button2.pack()
canvas_Main = Canvas(root, bg='#ffffff', width = 500, height = 500)
canvas_Main.pack()
tut = RawTurtle(canvas_Main)
tut.speed('fastest')
tut.color('red', 'yellow')
tut.begin_fill()
while True:
tut.forward(200)
tut.left(170)
if abs(tut.pos()) < 1:
break
tut.end_fill()
root.mainloop()
I am having this issue with Python Tkinter. I am trying to make a user interface form screen which requires the user to enter values into entry box's displayed on screen. I have set it so the two Entry Box's are in the same class (that class being the interface screen). The problem is that while I type into one of the box's, the text which I type not only displays in the box in which I am typing into, but also in the other box.
Below is the code in question.
class GenericSkeleton: # The template for all the screens in the program
def __init__(self):
self.GenericGui = Tk()
self.GenericGui.title('Radial Arc Calculator')
self.GenericGui.geometry('360x540')
self.GenericGui.resizable(width = FALSE, height = FALSE)
Label(self.GenericGui,text = 'Radial Arc Calculator',font = ('Ariel',18)).place(x=65,y=35)
def destroy(self):
self.GenericGui.destroy()
class InputScreen(GenericSkeleton):
def __init__(self):
GenericSkeleton.__init__(self)
Button(self.GenericGui,text = 'CALCULATE',height = 1, width = 25, command = calculate, font = ('TkDefaultFont',14)).place(x=37,y=400)
Button(self.GenericGui,text = 'CLOSE',height = 1, width = 11, command = close, font = ('TkDefaultFont',14)).place(x=37, y=450)
Button(self.GenericGui,text = 'HELP', height = 1, width = 11, command = DisplayHelp, font = ('TkDefaultFont',14)).place(x=190, y=450)
Label(self.GenericGui,text = 'Enter Radius (mm):', font = ('TkDefaultFont',14)).place(x=37, y=180)
Label(self.GenericGui,text = 'Enter point distance (mm):', font = ('TkDefaultFont',14)).place(x=37, y=250)
Entry(self.GenericGui,textvariable = Radius, width = 10, font = ('TkDefaultFont',14)).place(x=210, y=180)
Entry(self.GenericGui,textvariable = Distance, width = 5, font = ('TkDefaultFont',14)).place(x=265, y=250)
run = InputScreen()
The entry box's are at the bottom of the code, I hope its enough/not too much to solve the problem.
The problem is that they both share the same textvariable (you use different variable names, but they have the same value which makes them the same in the eyes of tkinter). My advice is to not use the textvariable attribute. You don't need it.
However, if you remove the use of textvariable then you need to separate your widget creation from widget layout so that you can keep a reference to the widget. Then you can use the get method on the widget (rather than on the variable) to get the value:
self.entry1 = Entry(...)
self.entry2 = Entry(...)
self.entry1.place(...)
self.entry2.place(...)
Later, you can get the values like this:
radius = int(self.entry1.get())
distance = int(self.entry2.get())
If you do need the textvariable (usually only if you're using the trace feature of a tkinter variable), you must use a tkinter variable (StringVar, IntVar, etc) rather than a regular variable.
This is my code :
import sys
from tkinter import *
#first new screen
def next_screen(names):
for widget in names:
widget.place_forget()
buttonhyp = Button (text = "button1",fg = "blue",command = hypoténusegetdef())
buttonhyp.grid (row = 1,column = 2)
def forget_page1():
widgets = [mLabel1, button]
next_screen(widgets)
################################################################################
def hypténusegetdef ():
widgets1 = [buttonhyp]
nextscreen1(widgets1)
def next_screen(names):
for widget in names:
widget.place_forget()
hyplabel1 = Label (text = "This is my text")
#first page things
mGui = Tk ()
mGui.geometry("600x600+545+170")
mGui.title("MyMathDictionary")
mLabel1 = Label (text = "Welcome to MyMathDictionary. Press Next to continue.",
fg = "blue",bg = "white")
mLabel1.place (x= 150,y = 200)
button = Button (text = "Next", command = forget_page1 )
button.place(x = 275,y = 230)
mGui.mainloop()
What i'm trying to do is to open the program and get the user to click on "Next" and then to show another button which is called "button1" and when the user clicks on "button1" it shows up a text called which says "This is my text" in my code.But when i run it i click on "Next" and nothing shows up i checked and re- checked but nothing seems to work.Any help would be appreciated.
#
I am not an expert, but i will give it a try.
Firstly, import sys is not necessary. And importing all the objects from tkinter module using from tkinter import* is not recommended. You should use import tkinter or import tkinter as tk to avoid unexepcted consequences.
You have 2 functions with the same name. next_screen(names) which should not happen.
Instead of using widgets = [mLabel1, button] to hide the widgets, you should put them in a frame so that you can use winfo_children() to find all the children widgets.
You should put the parent widget name when you create buttons and labels. for example,
import tkinter as tk
root = tk.Tk()
mylabel = tk.Label(root,text='this is a label')
mylabel.pack()
root.mainloop()
In your first next_screen(names) function , you used grid method to display the button. You should not mix the grid method and place method.
This is something i came up with
import tkinter as tk
def Screen_1():
Clear(myframe)
mybutton2= tk.Button(myframe,text = "Button1", command = Screen_2)
mybutton2.pack()
def Screen_2():
Clear(myframe)
mylabel2= tk.Label(myframe,text = "This is my text",fg = "blue",bg = "white")
mylabel2.pack(side='top')
def Clear(parent):
for widget in parent.winfo_children():
widget.pack_forget()
root =tk.Tk()
myframe=tk.Frame(root)
myframe.pack()
mylabel1= tk.Label(myframe,text = "Welcome to MyMathDictionary. Press Next to continue.",fg = "blue",bg = "white")
mylabel1.pack(side='top')
mybutton1= tk.Button(myframe,text = "Next", command = Screen_1)
mybutton1.pack(side='bottom')
root.mainloop()
hope it helps!