Python widgets and button - python

I'm trying to add a "Done" button to my program that will print the content of both Entry widgets to a new box. I can get the button to appear, but I can't get the information to show up in a new box. What am I doing wrong?
from Tkinter import *
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.grid()
self._name = StringVar()
self._name.set("Enter name here")
self._age = IntVar()
self._age.set("Enter age here")
top = self.winfo_toplevel() # find top-level window
top.title("Entry Example")
self._createWidgets()
self._button = Button(self,
text = "Done")
self._button.grid(row = 1, column = 0, columnspan = 2)
def _createWidgets(self):
textEntry = Entry(self, takefocus=1,
textvariable = self._name, width = 40)
textEntry.grid(row=0, sticky=E+W)
ageEntry = Entry(self, takefocus=1,
textvariable = self._age, width = 20)
ageEntry.grid(row=1, sticky=W)
def _widget(self):
tkMessageBox.showinfo
# end class Application
def main():
Application().mainloop()

You need to assign an action to your button using command: option.
To get what is written in Entry you need to use get() method.
showinfo you need two arguments, one is the title, the other one is what is going to be shown.
Also you need to import tkMessageBox.
Here is a working example.
import Tkinter as tk
import tkMessageBox
class Example(tk.Frame):
def __init__(self,root):
tk.Frame.__init__(self, root)
self.txt = tk.Entry(root)
self.age = tk.Entry(root)
self.btn = tk.Button(root, text="Done", command=self.message)
self.txt.pack()
self.age.pack()
self.btn.pack()
def message(self):
ent1 = self.txt.get()
ent2 = self.age.get()
tkMessageBox.showinfo("Title","Name: %s \nAge: %s" %(ent1,ent2))
if __name__=="__main__":
root = tk.Tk()
root.title("Example")
example = Example(root)
example.mainloop()

Related

How to add a scrollbar to window made with tkinter

A simple quiz game
I got this code and I need scrollbars, I tried to search how to add it on stackoverflow (ScrolledWindow with tix...) but I still can't get something that works properly. Could someone help me?
from tkinter import *
from random import randint
root = Tk()
root.title("Quiz")
root.geometry("400x300")
class Window:
def __init__(self, question, answer):
self.text = [question, answer]
self.createLabel()
# self.createText()
self.createEntry()
self.createButton()
def retrieve_input(self):
# inputValue = self.textBox.get("1.0", "end-1c")
# print(inputValue)
if self.mystring.get() == self.text[1]:
print("Esatto. è " + self.text[1])
self.left['text'] = "Esatto"
def createLabel(self):
self.labelframe = LabelFrame(root, text="Domanda:")
self.labelframe.pack(fill="both", expand="yes")
self.left = Label(self.labelframe, text=self.text[0])
self.left.pack()
def createText(self):
self.textBox = Text(height=1)
self.textBox.pack()
def createEntry(self):
self.mystring = StringVar()
self.myentry = Entry(root, textvariable=self.mystring).pack()
def createButton(self):
self.but = Button(text="Click", command=self.retrieve_input)
self.but.pack()
for i in range(10):
one = randint(1, 10)
two = randint(1, 10)
Window("Quanto fa " + str(one) + "+" + str(two) + "?", str(one + two))
root.mainloop()
output
With ScrolledFrame it can look like this
I renamed Window into Question because it makes more sense
I use self.question and self.answer instead of self.text = [question, answer] to make it more readable.
I put classes and functions before root = tk.Tk() to make it more readable.
I use import tkinter as tk instead of from tkinter import * to make it more readable.
Question gets inner frame from ScrolledFrame and use as parent for LabelFrame. Other widgets use labelframe as parent.
BTW: you had entry = Entry(..).pack() which assign None to entry because pack()/grid()/place() returns None. I put pack() in next line and now I can get text directly from Entry (without StringVar)
Code
import tkinter as tk
from random import randint
# --- classes ---
class ScrolledFrame(tk.Frame):
def __init__(self, parent, vertical=True, horizontal=False):
super().__init__(parent)
# canvas for inner frame
self._canvas = tk.Canvas(self)
self._canvas.grid(row=0, column=0, sticky='news') # changed
# create right scrollbar and connect to canvas Y
self._vertical_bar = tk.Scrollbar(self, orient='vertical', command=self._canvas.yview)
if vertical:
self._vertical_bar.grid(row=0, column=1, sticky='ns')
self._canvas.configure(yscrollcommand=self._vertical_bar.set)
# create bottom scrollbar and connect to canvas X
self._horizontal_bar = tk.Scrollbar(self, orient='horizontal', command=self._canvas.xview)
if horizontal:
self._horizontal_bar.grid(row=1, column=0, sticky='we')
self._canvas.configure(xscrollcommand=self._horizontal_bar.set)
# inner frame for widgets
self.inner = tk.Frame(self._canvas, bg='red')
self._window = self._canvas.create_window((0, 0), window=self.inner, anchor='nw')
# autoresize inner frame
self.columnconfigure(0, weight=1) # changed
self.rowconfigure(0, weight=1) # changed
# resize when configure changed
self.inner.bind('<Configure>', self.resize)
self._canvas.bind('<Configure>', self.frame_width)
def frame_width(self, event):
# resize inner frame to canvas size
canvas_width = event.width
self._canvas.itemconfig(self._window, width = canvas_width)
def resize(self, event=None):
self._canvas.configure(scrollregion=self._canvas.bbox('all'))
class Question:
def __init__(self, parent, question, answer):
self.parent = parent
self.question = question
self.answer = answer
self.create_widgets()
def get_input(self):
value = self.entry.get()
print('value:', value)
if value == self.answer:
print("Esatto. è " + self.answer)
self.label['text'] = "Esatto"
def create_widgets(self):
self.labelframe = tk.LabelFrame(self.parent, text="Domanda:")
self.labelframe.pack(fill="both", expand=True)
self.label = tk.Label(self.labelframe, text=self.question)
self.label.pack(expand=True, fill='both')
self.entry = tk.Entry(self.labelframe)
self.entry.pack()
self.button = tk.Button(self.labelframe, text="Click", command=self.get_input)
self.button.pack()
# --- main ---
root = tk.Tk()
root.title("Quiz")
root.geometry("400x300")
window = ScrolledFrame(root)
window.pack(expand=True, fill='both')
for i in range(10):
one = randint(1, 10)
two = randint(1, 10)
Question(window.inner, "Quanto fa {} + {} ?".format(one, two), str(one + two))
root.mainloop()

Cannot create Entry widget with tkinter

I'm having some trouble creating an entry widget with tkinter. I've imported the necessary modules and have already created several buttons and check boxes. However I cannot figure out how to properly initialize the Entry. Here is my relevant code:
# Necessary Modules.------------------------------------------------------------
import win32com.client as win32
import re
from tkinter import *
from tkinter.filedialog import askopenfilename
import tkinter.messagebox
# Class for selecting the file.-------------------------------------------------
class FilenameClass():
def __init__(self):
self.location = 'User Import.txt'
def getFile(self, identity):
self.file_opt = options = {}
options['defaultextension'] = '.txt'
options['filetypes'] = [('Text Document (.txt)', '.txt'),
('all files', '.*')]
self.filename = askopenfilename(**self.file_opt)
if self.filename:
if 'User Import' in identity:
self.location = self.filename
app.get_txt_File['bg'] = '#0d0'
user_file = open(self.filename, 'r')
user_total = user_file.read()
remove_lines = user_total.splitlines()
for user in remove_lines:
regex_tab = re.compile('\\t')
user_info = regex_tab.split(user)
app.users.append(user_info)
else:
app.loadButton['bg'] = '#e10'
# Main Class.-------------------------------------------------------------------
class Application(Frame, Tk):
def __init__(self, master=None):
Frame.__init__(self, master)
self.users = []
self.fileOBJtxt = FilenameClass()
self.createWidgets()
def createWidgets(self):
# Define the default values for the options for the buttons
# Grid layout options
self.rowconfigure(0, minsize=5)
self.width = 54
self.grid(padx=5)
self.loadButton_gopt = {'row':1,'column':1,'padx': 2, 'pady': 5}
self.loadButton_wopt = {'width': round(self.width),'bg':'#e10'}
self.loadButton()
self.trainingCheckBox()
self.signatureInput()
def loadButton(self):
'''Button that calls the filename class which allows the user to select
the text file they wish to use.'''
self.get_txt_File = Button(self, text="Load User List", \
command=lambda: self.fileOBJtxt.getFile('User Import'))
for key, value in self.loadButton_wopt.items():
self.get_txt_File[key] = value
self.get_txt_File.grid(**self.loadButton_gopt)
def trainingCheckBox(self):
self.training_var = IntVar()
self.training = Checkbutton(text="Include training video?", \
variable=self.training_var).grid(row=2, sticky=W)
def signatureInput(self):
Label(text="Signature Name").grid(row=4, sticky=W)
entry = Entry(bg='#fff', width=50)
entry.grid(row=4, column=1, columnspan=4)
# Initialization parameters.----------------------------------------------------
if __name__ == '__main__':
app = Application()
app.master.title('User Notification Tool')
app.master.geometry('405x550+100+100')
app.master.resizable(width=False, height=False)
app.mainloop()
I'm not seeing any tracebacks, but I can't seem to get my Entry box to show up. What am I doing wrong?
EDIT: added entire code.
The problem with your entry field is you have not told it what frame/window to be placed in.
Change:
entry = Entry(bg='#fff', width=50)
To:
entry = Entry(self, bg='#fff', width=50)
Make sure you always provide the window/frame that a widget is going to be placed in as the first argument. In this case it is self as self refers to a frame.
Keep in mind that your program will not be able to get() the string inside of your entry field because you have not defined it as a class attribute. So most likely you will need to change
This:
entry = Entry(bg='#fff', width=50)
entry.grid(row=4, column=1, columnspan=4)
To This:
self.entry = Entry(self, bg='#fff', width=50)
self.entry.grid(row=4, column=1, columnspan=4)
This change will be necessary in order for the rest of your application to be able to read or write to the entry widget.
Change
entry = Entry(bg='#fff', width=50)
to
entry = tk.Entry(bg='#fff', width=50)

cannot get python slave variable to update control

I create a StringVar, slave it to a label, change the value of the StringVar, and the label does not update.
class DlgConnection:
def start(self)
self.dlgConnection = Tk()
self.dlgConnection.title("Connection")
self.dlgConnection.geometry("380x400")
self.dlgConnection.resizable(width=False,height=False)
self.statusText = StringVar()
self.lStatusText = Label(self.dlgConnection, width=80, anchor="w", textvariable=self.statusText)
self.lStatusText.place(x = 0, y = 360, width=380, height=25)
self.setStatus("Welcome 2")
def setStatus(self, status_text):
print(status_text) #the print is just to show me I changed the text
self.statusText.set(status_text)
self.lStatusText.update() # I tried this out of desperation
I rewrote your code to something that works. The window opens with the text "Initial" and then once a second switches between "Welcome 1" and "Welcome 2".
from tkinter import *
from time import sleep
class DlgConnection(Frame):
def __init__(self, master):
Frame.__init__(self, master)
master.title("Connection")
master.geometry("380x400")
master.resizable(width=False,height=False)
self.statusText = StringVar()
self.statusText.set('Initial')
self.lStatusText = Label(master, width=80, anchor="w", textvariable=self.statusText)
self.lStatusText.place(x = 0, y = 360, width=380, height=25)
self.pack()
def setStatus(self, status_text):
print(status_text) #the print is just to show me I changed the text
self.statusText.set(status_text)
self.update_idletasks()
root = Tk()
dlgConnection = DlgConnection(root)
dlgConnection.update()
for i in range(6):
sleep(1) # Need this to slow the changes down
dlgConnection.setStatus('Welcome 2' if i%2 else 'Welcome 1')
This question is very similar to Update Tkinter Label from variable

Update User interface when a button is pressed Tkinter

So basically i want the user interface to be updated when a user presses the start button, however when i call the maininit function it returns an error saying that root is not defined, is there any way i can get around this?
from PIL import Image, ImageTk
from Tkinter import Tk, Label, BOTH,W, N, E, S, Entry, Text, INSERT, Toplevel
from ttk import Frame, Style, Button, Label
import Tkinter
import Callingwordlist
class MainGameUI(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Type!")
self.pack(fill=BOTH, expand=1)
style = Style()
style.configure("TFrame", background="black")
Type = Image.open("Type!.png")
Typet = ImageTk.PhotoImage(Type)
label3 = Label(self, image=Typet)
label3.image = Typet
label3.place(x=0, y=0)
self.pack(fill=BOTH, expand=1)
MenuButton = Button(self, text="Main Menu")
MenuButton.pack()
MenuButton.place(x=560,y=20,height = 80,width = 100)
QuitButton = Button(self,text="Quit",command=self.parent.destroy)
QuitButton.pack()
QuitButton.place(x=680,y=20,height = 80,width = 100)
StartButton = Button(self, text="Start",command=maininit)
StartButton.pack()
StartButton.place(x=440,y=20,height=80,width=100)
def maininit():
entry1 = Entry(root,font =("Courier",38), width = 22)
entry1.pack(ipady=10)
entry1.config(bg="#CEF6F5")
entry1.place(x=90,y=200)
entry2 = Entry(root,font =("Courier",38), width = 22)
entry2.pack(ipady=10)
entry2.config(bg="#CEF6F5")
entry2.place(x=90,y=350)
text1 = Text(root,width=23,height=1,font=("Courier",38))
text1.pack()
text1.config(bg="black",fg="white",bd=0)
text1.place(x=90,y=150)
text1.insert(INSERT,"Hello")
text2 = Text(root,width=23,height=1,font=("Courier",38))
text2.pack()
text2.config(bg="black",fg="white",bd=0)
text2.place(x=90,y=300)
text2.insert(INSERT,"Test")
dtext = Text(root,font=("Courier",28),width=10,height=1)
dtext.pack()
dtext.config(bg="black",fg="white",bd=0)
dtext.insert(INSERT,"Difficulty")
dtext.place(x=90,y=500)
atext = Text(root,font=("Courier",28),width=8,height=1)
atext.pack()
atext.config(bg="black",fg="white",bd=0)
atext.insert(INSERT,"Accuracy")
atext.place(x=595,y=500)
dentry = Text(root,font=("Courier",28),width=1,height=1)
dentry.pack()
dentry.config(bg="white",bd=0)
dentry.place(x=180,y=550)
dentry.insert(INSERT,"Test")
def main():
root = Tk()
root.geometry("860x640+300+300")
app = MainGameUI(root)
root.mainloop()
if __name__ == '__main__':
main()
In your application, root is a locally defined variable confined to main(). You need to somehow pass root as an argument to maininit. Here is one way to do this:
First, change maininit() so that it accepts a parameter root:
def maininit(root):
...
Now, change the callback on StartButton so it passes maininit() the root object:
class MainGameUI(Frame):
...
def initUI(self):
...
StartButton = Button(self, text="Start",command=lambda: maininit(self.parent))
...
You are defining root inside a function, whose calling namespace is not available to the maininit() function. If you omit the definition of main() and instead write
if __name__ == "__main__":
root = Tk()
root.geometry("860x640+300+300")
app = MainGameUI(root)
root.mainloop()
root will then be defined in the global module namespace, where it IS available to the code in the function.

Get value from Entry of Tkinter

Similar questions have been asked, but none of them address the particular way my script is constructed:
from Tkinter import *
from ttk import *
class Gui(Frame):
def __init__(self, parent):
Frame.__init__(self, parent) #Gui inherits from built in Frame Class
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Shoes Ware")
self.pack(fill=BOTH, expand=1)
run_val = Entry(self)
run_val["width"] = 5
run_val.place(x=80, y=40)
quit_B = Button(self, text="Submit", command=self.submit)
quit_B.place(x=130, y=170)
def submit(self):
value = run_val.get()
print value
self.quit()
def main():
root = Tk()
root.geometry("300x200+50+50")
app = Gui(root)
root.mainloop()
if __name__ == '__main__':
main()
I get "NameError: global name 'run_val' is not defined" when I hit the submit button. What am I doing wrong here. Right now the print statement is just to check my work. Later on, I'll be using that value in a program.
You are not storing the reference to the Entry widget in initUI.
def initUI(self):
# ...
self.run_val = Entry(self)
self.run_val["width"] = 5
self.run_val.place(x=80, y=40)
Then you can retrieve the value of self.run_val.get() without any problem.

Categories

Resources