Show tkinter widget when checkbox is checked - python-3.x

I'm trying to make the entry widget show once the checkbutton is checked and hide when it's not.
from tkinter import *
master = Tk()
master.geometry('500x400')
other = IntVar()
Checkbutton(master, text="Other", variable=other, command=toggle()).grid(row=10, sticky=W)
def toggle():
if other.get()==1:
Entry(master,width=50).grid(row=11, sticky=W)
else:
Entry(master,width=50).grid_remove()

Try this:
from tkinter import *
def toggle():
if other.get():
ent.grid(row=11, sticky=W)
else:
ent.grid_forget()
master = Tk()
master.geometry('500x400')
other = BooleanVar()
Checkbutton(master, text="Other", variable=other, command=toggle).grid(row=10, sticky=W)
ent=Entry(master,width=50)
master.mainloop()

Related

Python/tkinter - Getting the current value of the checkbox variable

I'd like to print the current value of the checkbox variable. Instead I get the last before the click. what am I doing wrong?
import tkinter as tk
def widget(frame):
chbx_value = 0
widget_col_span = 1
# widgets checkbox
var_c = tk.IntVar(master=frame, value=chbx_value)
widget_c = tk.Checkbutton(master=frame, text='', variable=var_c)
widget_c.bind("<ButtonRelease>", lambda event: print(var_c.get()))
widget_c.grid(row=0, column=0, columnspan=widget_col_span, padx=1, pady=1, sticky="ns")
root = tk.Tk()
root.title('My Window')
widget(root)
root.mainloop()
The event <ButtonRelease> obviously occurs before your variable has changed. My advice would be to use the command kwarg in the Checkbutton constructor. Besides, it probably makes more sense to use a boolean as variable:
import tkinter as tk
def widget(frame):
widget_col_span = 1
# widgets checkbox
var_c = tk.BooleanVar(master=frame)
widget_c = tk.Checkbutton(master=frame, text='', variable=var_c, command=lambda: print(var_c.get()))
widget_c.grid(row=0, column=0, columnspan=widget_col_span, padx=1, pady=1, sticky="ns")
root = tk.Tk()
root.title('My Window')
widget(root)
root.mainloop()

name 'main_window' is not defined

from tkinter import *
def create_main_window():
global main_window
main_window = Toplevel()
main_window.update()
entrance_window = Tk()
first_text_label = Label(entrance_window, text="you are in:").grid(row=0, column=0)
place_entry = Entry(entrance_window).grid(row=0, column=1)
submit_button = Button(entrance_window, text="Submit", command=create_main_window).grid(row=1, column=0, columnspan=2)
Label(main_window, text=f"{place_entry}").pack()
entrance_window.mainloop()
the program should open a new window with the text from the entry box from the first window but it either shows None if I write
Label(main_window, text=f"{place_entry}").pack()
in the create_main_window or it gives me an error saying that main_window is not defined if I write it after the button code.
Can someone help with this?
Try this:
from tkinter import *
def create_main_window():
global main_window
main_window = Toplevel(main_window)
label = Label(main_window, text=f"{place_entry.get()}")
label.pack()
# main_window.update() # This is useless
entrance_window = Tk()
first_text_label = Label(entrance_window, text="You are in:")
first_text_label.grid(row=0, column=0)
place_entry = Entry(entrance_window)
place_entry.grid(row=0, column=1)
submit_button = Button(entrance_window, text="Submit", command=create_main_window)
submit_button.grid(row=1, column=0, columnspan=2)
entrance_window.mainloop()
I moved the label creation inside create_main_window. Also please note that using var = a().b(), saves what ever b() returns inside var. That is why when you use var = Entry(...).pack(...), var is always None.
This is because you are trying to add a Label to an object that doesn't exist. Move the Label function to the create_main_window() function, like below:
from tkinter import *
def create_main_window():
global main_window, entrance_window
main_window = Toplevel()
place_entry = Entry(entrance_window).grid(row=0, column=1)
Label(main_window, text=f"{place_entry}").pack()
main_window.update()
entrance_window = Tk()
first_text_label = Label(entrance_window, text="you are in:").grid(row=0, column=0)
submit_button = Button(entrance_window, text="Submit", command=create_main_window).grid(row=1, column=0, columnspan=2)
entrance_window.mainloop()

Confused about binding the enter key in tkinter

This is a search bar program and once enter is hit it will open google with whatever I searched:
import tkinter as tk
from tkinter import ttk
import webbrowser
root = tk.Tk()
root.title("Search Bar")
label1 = ttk.Label(root, text="Query")
label1.grid(row=0, column=0)
entry1 = ttk.Entry(root, width=50)
entry1.grid(row=0, column=1)
def callback():
webbrowser.open("http://google.com/search?q="+entry1.get())
def get(event):
webbrowser.open("http://google.com/search?q=" + entry1.get())
button1 = ttk.Button(root, text="Search", width=10, command=callback)
button1.grid(row=0, column=2)
entry1.bind("<Return>", get)
root.mainloop()
What I'm most confused about is why did I need a second function [get(event)] in order to bind the enter key at entry1.bind("<Return>", get). Why couldn't I just put entry1.bind("<Return>", callback) (which is for the button). For some reason, the enter bind function requires a parameter and I'd just like an explanation as to why that is? Even though whatever is in the parameter is not being called.
You can use event=None in
def callback(event=None):
and then you can use with command= and bind()
bind() will run it with event, command= will run it without event and it will use None
import tkinter as tk
from tkinter import ttk
import webbrowser
def callback(event=None):
webbrowser.open("http://google.com/search?q="+entry1.get())
root = tk.Tk()
root.title("Search Bar")
label1 = ttk.Label(root, text="Query")
label1.grid(row=0, column=0)
entry1 = ttk.Entry(root, width=50)
entry1.grid(row=0, column=1)
button1 = ttk.Button(root, text="Search", width=10, command=callback)
button1.grid(row=0, column=2)
entry1.bind("<Return>", callback)
root.mainloop()
bind() can be used with different events and objects so it send this information to function - ie. event.widget - so you can bind the same function to different objects.
def callback(event=None):
print(event)
if event: # if not None
print(event.widget)
You can use
def callback(event=None):
Or u can pass None as parameter
import tkinter as tk
from tkinter import ttk
import webbrowser
root = tk.Tk()
root.title("Search Bar")
label1 = ttk.Label(root, text="Query")
label1.grid(row=0, column=0)
entry1 = ttk.Entry(root, width=50)
entry1.grid(row=0, column=1)
def callback():
webbrowser.open("http://google.com/search?q="+entry1.get())
def get(event):
webbrowser.open("http://google.com/search?q=" + entry1.get())
button1 = ttk.Button(root, text="Search", width=10, command=lambda x=None:get(x))
button1.grid(row=0, column=2)
entry1.bind("<Return>", get)
root.mainloop()

How can i create a Modal Dialogue Box by messagebox.showerror

How can I create a Modal Dialogue Box by messagebox.showerror?
messagebox.showerror("Error", "No downloader.exe found")
When I create a messagebox, I found I can move the root windows.
and i need to create a Modal Dialogue Box like filedialog.askopenfilename.
filedialog.askopenfilename(initialdir = self.get_path()+ '/bin', filetypes=[("BIN Files", ".bin")])
here's the codes:
import tkinter
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
import os
class Application(Frame):
def createWidgets(self, main_frame):
#self.llabel = Label(main_frame, text="Ready", width=20, bg="turquoise", font = ftLabel)
#self.llabel.grid(row=0, column=0, sticky=W+E) #columnspan=2
self.frame1 = Frame(main_frame)
self.frame1.grid(row=0, column=0, columnspan=2, sticky=W+E+N+S)
self.addr = StringVar()
self.addrtext = Entry(self.frame1, width=20, textvariable = self.addr)
self.addrtext.grid(row=0, column=0, sticky=W+E+N+S)
self.addr.set("0x0")
self.bfile = Button(self.frame1, text='BIN File', width=20)
self.bfile.grid(row=0, column=1, sticky=W+E+N+S)
messagebox.showerror("Error", "No downloader.exe found")
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack(fill=BOTH, expand=1)
main_frame = Frame(master)
main_frame.pack(fill="y", expand=1)
self.createWidgets(main_frame)
self.dl_thread = 0
if __name__=="__main__":
root = Tk()
#lock the root size
root.resizable(False,False)
app = Application(master=root)
app.mainloop()
I tried your code and messagebox.showerror is modal to me.
Maybe there is something else in your code (threads?) or maybe it's
dependent on your environment.
For reference, my entire code:
from tkinter import *
from tkinter import messagebox
root = Tk()
def do(): messagebox.showerror("Error", "No downloader.exe found")
b = Button(root, text='Dialog', command=do)
b.pack()
root.mainloop()
If that doesn't work you might want to take a look at: Tkinter messagebox not behaving like a modal dialog

Multiple line text entry box in python

In python i have been making a text editor like Microsoft word but i don't know how to make a text entry box for the user to put input. Here is my code! (ps thank you!)
from tkinter import *
import sys
def doNothing():
print("Test")
root = Tk()
root.title("TextEditor")
root.geometry("300x200")
menu = Menu(root)
root.config(menu=menu)
subMenu = Menu(menu)
menu.add_cascade(label="File", menu=subMenu)
subMenu.add_command(label="New Project...", command =doNothing)
subMenu.add_command(label="Save", command=doNothing)
subMenu.add_separator()
editMenu = Menu(menu)
menu.add_cascade(label="Edit", menu=editMenu)
editMenu.add_command(label="Undo",command=doNothing)
root.mainloop()
You can do that like this:
TextArea = Text()
TextArea.pack(expand=YES, fill=BOTH)
If you want a scrollbar with it:
TextArea = Text()
ScrollBar = Scrollbar(root)
ScrollBar.config(command=TextArea.yview)
TextArea.config(yscrollcommand=ScrollBar.set)
ScrollBar.pack(side=RIGHT, fill=Y)
TextArea.pack(expand=YES, fill=BOTH)
Hope this helped, good luck!
It is an old question but currently following is a very good method for scrollable multiline text entry:
ScrolledText(mainwin, width=50, height=5).pack()
Full program:
from tkinter import *
from tkinter.scrolledtext import ScrolledText
mainwin = Tk()
ScrolledText(mainwin, width=50, height=5).pack()
mainwin.mainloop()
Following demo application shows its usage further and comparison with entry box (for python3):
from tkinter import *
from tkinter.scrolledtext import ScrolledText
mainwin = Tk()
Label(mainwin, text="An Entry Box:").grid(row=0, column=0)
ent = Entry(mainwin, width=70); ent.grid(row=0, column=1)
Button(mainwin, text="Print Entry", command=(lambda: print(ent.get()))).grid(row=0, column=2, sticky="EW")
Label(mainwin, text="ScrolledText Box:").grid(row=1, column=0)
st = ScrolledText(mainwin, height=5); st.grid(row=1, column=1)
Button(mainwin, text="Print Text", command=(lambda: print(st.get(1.0, END)))).grid(row=1, column=2, sticky="EW")
Button(mainwin, text="Exit", command=sys.exit).grid(row=2, column=0, columnspan=3, sticky="EW")
mainwin.mainloop()

Resources