How to remove error made when adding exit button? - python

from tkinter import*
import sqlite3
class login:
def __init__(self,root):
self.root=root
self.root.geometry("250x250")
self.root.title("Login")
self.root.resizable(False,False)
self.var_username=StringVar() ##variables
self.var_password=StringVar()
username=Label(self.root,text="Username",font=("Bahnschrift SemiBold",15),bg="white",fg="black").place(x=15,y=20)
username=Entry(self.root,textvariable=self.var_username,font=("Bahnschrift SemiBold",15),bg="white",fg="black").place(x=125,y=20,width=115)
password=Label(self.root,text="Password ",font=("Bahnschrift SemiBold",15),bg="white",fg="black").place(x=15,y=60)
password=Entry(self.root,textvariable=self.var_password,font=("Bahnschrift SemiBold",15),bg="white",fg="black").place(x=125,y=60,width=115)
_exit=Button(self.root,text="exit",command=self.destroy,font=("Bahnschrift SemiBold",15),bg="green",fg="white",cursor="hand2").place(x=125,y=100,width=55,height=28)
if __name__ == "__main__":
root=Tk()
obj=login(root)
root.mainloop()
it comes up with a attribute error and im not to sure how to fix it because it works in other pieces of code.

You might want to change the button command from self.destroy to self.root.destroy.
Button(self.root,
text="exit",
command=self.root.destroy,
font=("Bahnschrift SemiBold",15),
bg="green",
fg="white",
cursor="hand2").place(x=125, y=100, width=55, height=28)
As a side note, doing label = Label(root, ...).place(x=...) does not do anything (for any widget). The value of label will be stored as None and you wont be able to reference that later to change its properties. If this is the goal, then simply: Label(root, ...).place(x=...) would work. Otherwise, you'll have to create widgets in one line, and place them in the next lline
PS: It is a recommended practice to also include the error faced in order for ease of diagnosing. Please do refer How to ask for asking further questions.

Related

Python Tkinter Gui Hide and show key bind

0 iq Question incoming, i wanna know is there a way i can show and hide a tkinter gui with insert key, ive searched online but wasnt able to find an answer, for example like csgo menus.
Thank you.
Please make sure to always include what you have tried and your research. Follow these guidelines to create a minimal reproducible example.
What you are trying to accomplish can be done with this Tkinter template:
from tkinter import *
root = Tk()
# Open new window
def launch():
global second
second = Toplevel()
second.title("Child Window")
second.geometry("400x400")
# Show the window
def show():
if event.keysym == "Insert"
second.deiconify()
# Hide the window
def hide():
if event.keysym == "Insert"
second.withdraw()
# Add Buttons
Button(root, text="launch Window", command=launch).pack(pady=10)
Button(root, text="Show", command=show).pack(pady=10)
Button(root, text="Hide", command=hide).pack(pady=10)
root.mainloop()

Tkinter winfo_ismapped() method not working

I have a program in python which in which I use Listboxes, buttons and labels. So today I came conflicting with a problem. I wanted to make my listbox appear when a button is clicked and disappear when the same button is clicked again. How can I achieve this? I tried using the winfo_ismapped() method but didnt seem to work. I think I might have done something crazy. If so, please point it out and give me a corrected answer. Else please tell me a better way to do it.
My Code:
import tkinter as tk
from tkinter import *
root = tk.Tk()
root.geometry('500x500')
def showMenu():
overlay = Listbox(root, bg="green", height=22, width=58)
if overlay.winfo_ismapped() == 0:
overlay.place(x=0,y=35)
else:
overlay.placeforget()
button = tk.Button(root,text="place/remove", command=showMenu)
button.place(x=0,y=0)
root.mainloop()
Actually it comes when I press the button but hide after I press it again.
In the same way I have another issue with these labels too.
CODE:
import tkinter as tk
root = tk.Tk()
def placeFun():
successtext = tk.Label(root, text="Success", anchor='nw', bg="#212121", fg="#ff3300",font=("Consolas", 15, "bold"))
if successtext.winfo_ismapped() == 0:
successtext.place(x=0,y=50)
else:
succestext.forget()
button = tk.Button(root, text='place/rem', width=25, command=placeFun)
button.place(x=0,y=0)
root.mainloop()
Please Note: I want a professional way to handle this, I said it because, I know a way in which we use variables like:
globalvartimes = 0
def somefunc():
if times % 2 == 0:
show the listbox
global times
times += 2
else:
remove the listbox
times += 1
*This shows the listbox when times is even and remove it when it's odd.
These makes the code look non-professional and long.
The problem is every time showMenu() is called another Listbox is created. To fix that, create the Listbox outside of the function (so it's a global).
(I also noticed you misspelled the name of place_forget() method.)
import tkinter as tk
from tkinter import *
root = tk.Tk()
root.geometry('500x500')
def showMenu():
if overlay.winfo_ismapped(): # Placed?
overlay.place_forget()
else:
overlay.place(x=0,y=35)
overlay = Listbox(root, bg="green", height=22, width=58)
button = tk.Button(root,text="place/remove", command=showMenu)
button.place(x=0,y=0)
root.mainloop()
This looks like it is what is wrong with your Label example, too.
Note: If you want to write "professional" code, I suggest you read (and start following) the
PEP 8 - Style Guide for Python Code.

Closing a second Tkinter window doesn't work

Imagine the following very simple example:
from tkinter import *
from tempFunctions import *
startingWin = Tk()
button = Button(startingWin, text="Open Other Win", command=lambda: openSecondWin()).grid(row=0, column=0, padx=30, pady=30)
startingWin.mainloop()
The output is simply as following:
No if I click on the button, I open the second Win like:
The second window has the following code in tempFunctions.py:
from tkinter import *
def openSecondWin():
secondWin = Tk()
cancelButton = Button(secondWin, text="Cancel", command=secondWin.quit).grid(row=0, column=0, padx=30, pady=30)
secondWin.mainloop()
I expect that when I press cancel, the secondWin should close. That doesn't happen. What I get is that when I click cancel, the second Win doesn't close. However, if click twice both windows (startingWin and secondWin) close together. Why?
Is there a logical explanation for this? Thanks!
UPDATE:
Trying with binding results in the same problem.
Also making the second win as Toplevel doesn't help.
The problem was that I was using quit(). However, in case of multiple windows, one should use destroy() according to the answer here. That solved my problem.

Tkinter text insert: " 'Nonetype' object has no attribute 'insert'

Relatively new to coding in general, and have been trying to create a simple chat client for Python. Trying to work the GUI, and have encountered the problem shown below.
I have a functioning GUI and use the "example.get()" function to retrieve the string text from an entry box. The program then prints the text to the command prompt (Just to prove it's been retrieved) and then should place it in a text box, however it gives me a "Nonetype" error. Code is below. Does anyone have any idea how to fix this?
Thanks
from tkinter import *
#Create GUI
root=Tk()
root.title("Chat test")
root.geometry("450x450+300+300")
#Declare variables
msg=StringVar()
#Get and post text to chat log
def postaction():
msg1=msg.get()
print(msg1)
chatlog.insert(INSERT,msg1+'\n')
root.mainloop()
#Build GUI components
chatlog=Text(root, height=10, state=DISABLED).pack(side=TOP, fill=X)
entry=Entry(root, textvariable=msg).pack(side=BOTTOM, fill=X)
button=Button(root, command=postaction, text="Button").pack()
The .pack method of a widget always returns None. So, you need to place the calls to .pack on their own line:
chatlog=Text(root, height=10, state=DISABLED)
chatlog.pack(side=TOP, fill=X)
entry=Entry(root, textvariable=msg)
entry.pack(side=BOTTOM, fill=X)
button=Button(root, command=postaction, text="Button")
button.pack()

Keep a menu open in Tkinter

I want to keep a menu cascade open, after a command button within the cascade is clicked. So it basically only closes when the user clicks anywhere else (like it would normally too). Can't seem to find a proper option or a method to open said menu in the callback. The invoke() function only works on buttons wihtin the cascade right? How would you go about that?
Yes, I know this was asked a long time ago, but I was curious if there was any way to accomplish this with tkinter, so I fiddled about for a while and figured out how to do it. I was unable to come up with a way to properly place the persistent menu where it was when it originally opened, but I have managed to make it persist in any location you request (I use upper-left corner of root window). And yes, I know this isn't a nice proper class based implementation, but I was just going for as simple a test as I could write without obscuring it with too many extraneous details.
try:
from tkinter import *
from tkinter.ttk import *
except:
from Tkinter import *
from ttk import *
root = Tk()
var = StringVar()
def menu_click(menu, item):
global root
var.set(item)
menu.post(root.winfo_rootx(), root.winfo_rooty())
root.option_add('*tearOff', False) # remove tearoff from all menus
Label(root, textvariable=var).pack() # just to give menu clicks some feedback
root.geometry('400x300')
menubar = Menu(root)
root['menu'] = menubar
menu_test = Menu(menubar)
menubar.add_cascade(menu=menu_test, label='Test')
menu_test.add_command(label='One', command=lambda: menu_click(menu_test, 'One'))
menu_test.add_command(label='Two', command=lambda: menu_click(menu_test, 'Two'))
menu_test.add_command(label='Three', command=lambda: menu_click(menu_test, 'Three'))
menu_cas = Menu(menu_test)
menu_test.add_cascade(menu=menu_cas, label='Four')
menu_cas.add_command(label='One', command=lambda: menu_click(menu_cas, 'Fourty One'))
menu_cas.add_command(label='Two', command=lambda: menu_click(menu_cas, 'Fourty Two'))
menu_cas.add_command(label='Three', command=lambda: menu_click(menu_cas, 'Fourty Three'))
root.mainloop()

Categories