Problem with Tkinter and creating a new window - python

I am quite new with Tkinter and am trying to create a new window using this script while keeping the current window but i am get the error
_init_() missing 1 required positional argument: 'parent'. I am not really sure what the reason is but I am assuming that the command function for my button isn't working the way I want it.
The script currently looks something like this:
from tkinter import simpledialog
from tkinter import *
class Additional(simpledialog.Dialog):
def body(self, master):
#input fields
Label(master, text="Picture 3 Path:").grid(row=1)
#input fields for tags
#add as needed
self.e1 = Entry(master)
self.e1.grid(row=1, column=1, ipadx=150)
return self.e1 # initial focus
def apply(self):
first = self.e1.get()
self.ttag1 = (first)
class Initial(simpledialog.Dialog):
def body(self, master):
#input fields for username and passwords
Label(master, text="Usernames:").grid(row=1),
self.e1 = Entry(master)
self.b1 = Button(master, text = "Add More", bg= 'grey', command= Additional)
self.b1.grid(row=6, column=2, ipadx=75)
self.e1.grid(row=1, column=1, columnspan=2, ipadx=50)
return self.e1 # initial focus
def apply(self):
first = self.e1.get()
self.tag1 = (first)
root = tk.Tk()
root.withdraw()
d = Initial(root)
toor = tk.Tk()
toor.withdraw()
I have tried changing it up but it seems that it's not working right. Any ideas?

When calling the Additional class through the button command, you are not specifying what the parent root should be, and therefore the class fails to initiate. You can solve this by passing the master using a lambda
self.b1 = Button(master, text="Add More", bg='grey', command=lambda: Additional(master))

Related

Checkbox always reads 0 in popup window - Tkinter

I have a GUI using Tkinter, it has a main screen and then when you press a button a popup window appears, where you select a checkbutton and then a email will get sent to you.
Not matter what I do, I cannot read the value of the checkbutton as 1 or True it always = 0 or False.
This is my code:
import tkinter as tk
from tkinter import *
import time
root = tk.Tk()
root.title('Status')
CheckVar1 = IntVar()
def email():
class PopUp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
popup = tk.Toplevel(self, background='gray20')
popup.wm_title("EMAIL")
self.withdraw()
popup.tkraise(self)
topframe = Frame(popup, background='gray20')
topframe.grid(column=0, row=0)
bottomframe = Frame(popup, background='gray20')
bottomframe.grid(column=0, row=1)
self.c1 = tk.Checkbutton(topframe, text="Current", variable=CheckVar1, onvalue=1, offvalue=0, height=2, width=15, background='gray20', foreground='snow', selectcolor='gray35', activebackground='gray23', activeforeground='snow')
self.c1.pack(side="left", fill="x", anchor=NW)
label = tk.Label(bottomframe, text="Please Enter Email Address", background='gray20', foreground='snow')
label.pack(side="left", anchor=SW, fill="x", pady=10, padx=10)
self.entry = tk.Entry(bottomframe, bd=5, width=35, background='gray35', foreground='snow')
self.entry.pack(side="left", anchor=S, fill="x", pady=10, padx=10)
self.button = tk.Button(bottomframe, text="OK", command=self.on_button, background='gray20', foreground='snow')
self.button.pack(side="left", anchor=SE, padx=10, pady=10, fill="x")
def on_button(self):
address = self.entry.get()
print(address)
state = CheckVar1.get()
print (state)
time.sleep(2)
self.destroy()
app = PopUp()
app.update()
tk.Button(root,
text="EMAIL",
command=email,
background='gray15',
foreground='snow').pack(side=tk.BOTTOM, fill="both", anchor=N)
screen = tk.Canvas(root, width=400, height=475, background='gray15')
screen.pack(side = tk.BOTTOM, fill="both", expand=True)
def latest():
#Other code
root.after(300000, latest)
root.mainloop()
The popup works perfectly, and the email will print when entered but the value of checkbox is always 0.
I have tried:
CheckVar1 = tk.IntVar() - No success
self.CheckVar1 & self.CheckVar1.get() - No success
Removing self.withdraw() - No success
I only have one root.mainloop() in the script, I am using app.update() for the popup window because without this it will not open.
I have checked these existing questions for solution and none have helped:
Self.withdraw - Can't make tkinter checkbutton work normally when running as script
Self.CheckVar1 - TKInter checkbox variable is always 0
Only one instance of mainloop() - Python tkinter checkbutton value always equal to 0
I have also checked very similar questions but I wasn't going to post them all.
Any help is appreciated.
The problem is that you have two root windows. Each root window gets its own internal tcl interpreter, and the widgets and tkinter variables in one are completely invisible to the other. You're creating the IntVar in the first root window, and then trying to associate it with a checkbutton in a second root window. This cannot work. You should always only have a single instance of Tk in a tkinter program.
because of variable scope
try to put CheckVar1 = IntVar() inside the class
use it with self like this
self.CheckVar1 = tk.IntVar() # object of int
self.CheckVar1.set(1) # set value
variable=self.CheckVar1 # passing to the checkbutton as parameter
state = self.CheckVar1.get() # getting value

How to retain the value of an entry field acquired in a popup toplevel window in tkinter?

I cannot get my code to pass the pop up text entry to a global variable i am also attempting to set this global variable as the default text in the entry field in all future instances.
Pop up -> Enter Filepath -> accept&close -> Re-open shows last filepath present as default -> if changed new filepath entry becomes default in future.
import tkinter as tk
from tkinter import ttk
from tkinter import *
master = tk.Tk()
Var1 = StringVar()
Filepath_Var = None
def A_Connect():
root = Tk()
root.title("Entry Field")
def entry_field():
global Filepath_Var
Filepath_Var = Var1.get()
tk.Label(root, text="filepath: ").grid(row=0)
e1 = tk.Entry(root, textvariable=Var1)
tk.Label(root, text="Item Number: ").grid(row=1)
e2 = tk.Entry(root)
#e1.insert(0, r"C:\Users\zxy\ghj\iugf\Bea\something.xlsx")
e1.insert(0, Var1.get())
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
Button(root, text = 'Accept', command = entry_field).grid(row=3, column=1,
sticky=W, pady=4)
root.mainloop()
note = ttk.Notebook(master)
tab1 = tk.Frame(note)
canvas7 = Canvas(tab1, width=520, height=350)
canvas7.pack()
A_Button = tk.Button(tab1, text="A",
width=12, height=3,command=A_Connect, anchor = 'w')
A_Button_Window = canvas7.create_window(20, 120, anchor = 'sw',
window = A_Button)
note.add(tab1, text = " Main ")
note.pack()
master.mainloop()
As a follow up to your earlier question, I encapsulated an example of the (bare bones) desired behavior in two classes:
The main App consists of a button that launches an entry popup; upon filling the fields and accepting, the value in the entry is provided to the App, and the popup closed.
The value entered is stored by the App, and used to populate the entry field of the entry fields in successive popups.
You will probably want to add confirmations and verifications before changing the defaults, and closing the popup, but here, you have the basic skeleton to attach this to.
import tkinter as tk
class PopUpEntry(tk.Toplevel):
def __init__(self, master, default_value=None):
self.master = master
super().__init__(self.master)
if default_value is None:
self.default_entry = 'C:*****\somthing.xlsx'
else:
self.default_entry = default_value
self.title("Entry Field")
tk.Label(self, text="Filepath: ").pack()
self.e1 = tk.Entry(self)
self.e1.insert(0, self.default_entry)
self.e1.pack()
tk.Button(self, text = 'Accept', command=self.entry_field).pack()
def entry_field(self):
self.default_entry = self.e1.get()
self.master.provide_entry_value(self.default_entry)
self.destroy()
class App(tk.Tk):
def __init__(self):
super().__init__()
self.pop_entry = tk.Button(self, text='launch entry', command=self.launch_entry)
self.pop_entry.pack()
self.default_entry_value = None
self.mainloop()
def launch_entry(self):
PopUpEntry(self, self.default_entry_value)
def provide_entry_value(self, value):
self.default_entry_value = value
print(self.default_entry_value)
App()

How Transfer cursor in tkinter?

i wrote bellow code in python 3.6.2 by tkinter,I want the cursor move to password textbox when user press Enter key in username textbox.
from tkinter import *
class Application(Frame):
def __init__(self,master):
super(Application, self).__init__(master)
self.grid()
self.create_main()
def create_main(self):
print("testing")
self.title = Label(self, text=" Stuck In The Circle ")
self.title.grid(row=0, column=2)
self.user_entry_label = Label(self, text="Username: ")
self.user_entry_label.grid(row=1, column=1)
self.user_entry = Entry(self)
self.user_entry.grid(row=1, column=2)
self.pass_entry_label = Label(self, text="Password: ")
self.pass_entry_label.grid(row=2, column=1)
self.pass_entry = Entry(self)
self.pass_entry.grid(row=2, column=2)
self.user_entry = Entry(self, justify="right")
self.pass_entry = Entry(self, justify="right")
self.sign_in_butt = Button(self, text="Sign In",command = self.logging_in)#SIGN IN BUTTON
self.sign_in_butt.grid(row=5, column=2)
def logging_in(self):
user_get = self.user_entry.get()
pass_get = self.pass_entry.get()
root = Tk()
root.title("Stuck in the Circle")
root.geometry("400x100")
app = Application(root)
root.mainloop()
How can do it?
This is actually a lot simpler than I expected it to be.
We can use .bind() to get a callback on the <Return> event. This means that every time the return character is pressed whenever the defined widget is in focus we get a callback.
In order to get it to cycle to the next widget we can use this answer from Bryan Oakley:
def focus_next_window(event):
event.widget.tk_focusNext().focus()
return("break")
text_widget=Text(...) text_widget.bind("<Tab>", focus_next_window)
Important points about this code:
The method tk_focusNext() returns the next widget in the keyboard
traversal hierarchy. the method focus() sets the focus to that widget
returning "break" is critical in that it prevents the class binding
from firing. It is this class binding that inserts the tab character,
which you don't want.
So, applying the same logic in our situation we can use something like the below:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.entry1 = Entry(self.root)
self.entry2 = Entry(self.root)
self.entry1.pack()
self.entry2.pack()
self.entry1.bind("<Return>", self.callback)
def callback(self, event):
event.widget.tk_focusNext().focus()
root = Tk()
App(root)
root.mainloop()

Access state of object (tkinter, Python3) beginner's level

What I want to get: change of checkbox state changes the state of the Entry widget from 'disabled' into 'normal'. (checkbox off = Entry disabled, checkbox on = Entry normal).
My problem is that I don't know how to access and update the state of entry.
My code:
from tkinter import *
from tkinter import ttk
class App(Frame):
def __init__(self, master):
ttk.Frame.__init__(self, master, padding='20')
self.grid()
self.create_checkbox()
self.create_entry()
def create_checkbox(self):
self.limit = BooleanVar()
Checkbutton(self,
text='Limit length',
variable= self.limit,
command= self.state_update,
).grid(row=1, column=1, sticky=W)
def create_entry(self):
self.entry_low = StringVar()
Entry(self,
width=6,
textvariable=self.entry_low,
state='disabled',
).grid(row=1, column=2, sticky=W)
def state_update(self):
self.entry_low.config(state="normal") #THIS OBVIOUSLY DOES NOT WORK
root = Tk()
root.title("Lottery")
app = App(root)
root.mainloop()
I'm beginner, so I'd be especially grateful for simple solutions.
Save a reference to the entry widget, then call the configure method. To make things easy, give your checkbutton the values for the states. That isn't strictly necessary, you can use a boolean and then translate that to the appropriate state.
def create_checkbox(self):
self.limit = StringVar(value="normal")
checkbutton = Checkbutton(..., onvalue="normal", offvalue="disabled", ...)
checkbutton.grid(...)
def create_entry(self):
self.entry_low = StringVar()
self.entry = Entry(self,
width=6,
textvariable=self.entry_low,
state='disabled',
)
self.entry.grid(row=1, column=2, sticky=W)
def state_update(self):
self.entry.config(state="normal") #THIS OBVIOUSLY DOES NOT WORK
Note: you need to call grid in a second step. grid(...) (as well as place) returns None. If you do x=Entry(...).grid(...), x will always be None.

Why is Tkinter Entry's get function returning nothing?

I'm trying to use an Entry field to get manual input, and then work with that data.
All sources I've found claim I should use the get() function, but I haven't found a simple working mini example yet, and I can't get it to work.
I hope someone can tel me what I'm doing wrong. Here's a mini file:
from tkinter import *
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
content = entry.get()
print(content) # does not work
mainloop()
This gives me an Entry field I can type in, but I can't do anything with the data once it's typed in.
I suspect my code doesn't work because initially, entry is empty. But then how do I access input data once it has been typed in?
It looks like you may be confused as to when commands are run. In your example, you are calling the get method before the GUI has a chance to be displayed on the screen (which happens after you call mainloop.
Try adding a button that calls the get method. This is much easier if you write your application as a class. For example:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text="Get", command=self.on_button)
self.button.pack()
self.entry.pack()
def on_button(self):
print(self.entry.get())
app = SampleApp()
app.mainloop()
Run the program, type into the entry widget, then click on the button.
You could also use a StringVar variable, even if it's not strictly necessary:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
For more information, see this page on effbot.org.
A simple example without classes:
from tkinter import *
master = Tk()
# Create this method before you create the entry
def return_entry(en):
"""Gets and prints the content of the entry"""
content = entry.get()
print(content)
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
entry.bind('<Return>', return_entry)
mainloop()
*
master = Tk()
entryb1 = StringVar
Label(master, text="Input: ").grid(row=0, sticky=W)
Entry(master, textvariable=entryb1).grid(row=1, column=1)
b1 = Button(master, text="continue", command=print_content)
b1.grid(row=2, column=1)
def print_content():
global entryb1
content = entryb1.get()
print(content)
master.mainloop()
What you did wrong was not put it inside a Define function then you hadn't used the .get function with the textvariable you had set.
you need to put a textvariable in it, so you can use set() and get() method :
var=StringVar()
x= Entry (root,textvariable=var)
Most of the answers I found only showed how to do it with tkinter as tk. This was a problem for me as my program was 300 lines long with tons of other labels and buttons, and I would have had to change a lot of it.
Here's a way to do it without importing tkinter as tk or using StringVars. I modified the original mini program by:
making it a class
adding a button and an extra method.
This program opens up a tkinter window with an entry box and an "Enter" button. Clicking the Enter button prints whatever is in the entry box.
from tkinter import *
class mini():
def __init__(self):
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
Button(master, text='Enter', command=self.get_content).grid(row=1)
self.entry = Entry(master)
self.entry.grid(row=0, column=1)
master.mainloop()
def get_content(self):
content = self.entry.get()
print(content)
m = mini()

Categories

Resources