My SQL Login Function to Switch Frames Doesn't Work - python

My login function doesn't accept the correct username and password when inputted.
So, I'm trying to make a book management system using sqlite3 that has a two frames in a Tkinter window, f1 and f2. f1 contains a login function where if the correct username and password from the database are inputted, it moves to another frame using tkinter. However, it always goes for the "else" condition and says the username and password are incorrect.
def Login():
Connect()
Username=StringVar()
Password=StringVar()
cursor.execute("SELECT * FROM Users WHERE username=? and password=?",(Username.get(), Password.get(),))
connection.commit()
users = cursor.fetchall()
print(users)
connection.commit()
if users is True:
f2.pack(fill='both', expand=1)
f1.pack_forget()
else:
label1=Label(root,text="Wrong username or password, please try again")
label1.place(x=350,y=300)
e2.delete(0, END)
It seems that I'm not getting anything back from the database with the SELECT command for some reason. Advice would really be appreciated!

You're calling Username.get() and Password.get() about a millisecond after creating those variables. There's no way for them to have any value than their initial value, which will be an empty string since you don't give them an explicit default value.
Instead of creating the variables in the function, you should call the get methods of an Entry widget, assuming your program uses Entry widgets. Or, whatever code calls Login must also pass in the username and password. It's not clear from your question where you expect those values to come from.

Related

TKinter. Tcl_AsyncDelete: cannot find async handler

I am running tkinter library in the Odoo15 for a specific purpose.
I have created a custom python interpreter to run python code inside odoo.
To handle user inputs i specially designed a concept and via tkinter i am taking inputs from user.
In a code there may be more than one inputs and so i need to open the window more than one time. for example taken one input, Entered, closed window and then repeat the same process till final user input.
So in that case, at some movement my server getting terminated with a runtime error:
Tcl_AsyncDelete: cannot find async handler
Aborted (core dumped)
can anyone guide me how can i resolve this please ?
import tkinter as tk
import gc
root=tk.Tk()
root.geometry('800x200+600+300')
name_var=tk.StringVar()
var_1 = ''
def submit():
name=name_var.get()
global %s
var_1 = name
root.destroy()
name_label = tk.Label(root, text = 'Enter value', font=('calibre',10, 'bold'))
name_entry = tk.Entry(root,textvariable = name_var, font=('calibre',10,'normal'))
sub_btn=tk.Button(root,text = 'Submit', command = submit)
name_label.grid(row=0,column=0)
name_entry.grid(row=0,column=1)
sub_btn.grid(row=2,column=1)
root.mainloop()
when there is a line like value = input("Enter value")
i am replacing that line with the above code to take user input.
Looking forward to hear on this .. thanks
Without a minimal reproducible example it is more of a guessing than an answer.
But due to your request, I'll try my best guess. The information how you code this section below, can be crucial.
In a code there may be more than one inputs
and so i need to open the window more than
one time. for example taken one input,
Entered, closed window and then repeat the
same process till final user input.
If you destroy the root window, the instance of tkinter.Tk() and you try to retrieve the users input (data located in tkinter) of the destroyed instance you could run into trouble. Instead of creating new instances of tkinter.Tk use tkinter.Toplevel. You could hide the root window in many ways. I.e with overrideredirect and transparency.
TL;DR
Make sure you use the same instance of tkinter.Tk() through out the whole session and or connect the new instance with your server and vice versa.
Hope it will work out for you, especially because I don't know about odoo.

Using a variable from an other class tkinter python

I'm using Tkinter (with python) to create a UI. How can I use the entry (which defines the user name) from one page on another page (thus another class)?
Basically, I need the user name to appear on several pages without asking the user to enter it each time.
you can make it a global variable.
global password
password_entry = tk.Entry(screen1, show="*", textvariable=password)
And then use it anywhere in your program
I don't know do you have any database which includes the usernames. If yes you can get it from there.
if not, so you can use global variable to keep username.
global username
username = textbox.get("1.0","end")

I have a tkinter entry box in python but I can't get the input from it into my code?

This is my code below :
from tkinter import *
login = Tk()
username_1 = Entry()
username_1.pack(side=TOP)
input_username = login.username_1.get("1.0", END)
username = input_username
loginInfo = {"user1": "blue", "user2": "yellow", "user3": "green"}
if username in loginInfo:
print('Username correct!')
login.mainloop()
This is my error:
'AttributeError: '_tkinter.tkapp' object has no attribute 'username_1'':
When you create widgets, you are creating children of the root window. However, these children are not attributes of the root window. Thus, login.username_1 is invalid, just as the error is telling you.
In this specific case, the widget is simply username_1 (eg: input_username = username_1.get("1.0", END)). However, even that won't work for the following reasons:
the get method of the entry doesn't take arguments. You need to do username_1.get().
you are calling get about one millisecond after the entry has been created, well before the user has a chance to enter anything.
With a GUI toolkit you can't think of your program running linearly from top to bottom. Instead, you set things up to initially appear, and then you need to write functions that respond to events such as key presses and button clicks. For example, you might want to create a button with the label "Login" that calls a function to check for valid credentials. It would be within that function that you call the get() method.
Can you please provide information about what your code is supposed to do?
If you just want to avoid this error - change line 6 for this:
input_username = username_1.get()

Tkinter I want to delete a frame and replace it with another

I recently started learning python and even more recently the Tkinter module. For practice I decided to create a window environment that works a bit like mySQL workbench. Everything was fine until I found out that submitting a second query doesn't actually remove the previous one.
My code for the button callback is as follows:
def queryBtnCallBack():
global query
global queryEntry
global resList
global resFrame
j=1
#Delete frame before showing next data
for widget in resFrame.winfo_children():
widget.destroy()
#For this one I also tried
#if resFrame != None:
# resFrame.destroy()
cursor = db.cursor()
resFrame = Tkinter.Frame()
#Check if user has given a correct input
try:
query = queryEntry.get()
cursor.execute(query)
data = cursor.fetchall()
#Let user know if something is wrong
except:
errorQLabel = Tkinter.Label(resFrame, text='Error. Please make sure your query is correct', bg='#99b3e6')
errorQLabel.grid(row=j+1, column=2)
resFrame.configure(background='#99b3e6')
resFrame.pack()
return
for i in data:
resList.append(i)
#Query Results window part
for i in range(len(resList)):
j += 1
resultLabel = Tkinter.Label(resFrame, text=resList[i], bg='#99b3e6')
resultLabel.grid(row=j, column=2)
resFrame.configure(background='#99b3e6')
#Pack the results frame
resFrame.pack()
The way I'm doing it now, it deletes the frame, but then puts the next one underneath the now-deleted one.
Any kind of help would be greatly appreciated.
Thank you in advance
Maybe you're trying to make this more complex than it needs to be. I'd suggest just keeping one big label and reconfiguring it with new text to show the new data, maybe with newlines inserted into the data to keep the sections separate. To get rid of the previous query from the entry widget, just do queryEntry.delete('0', 'end').

How to get a menu checkbutton to call a function in Python + Tkinter?

so, I'm now in a personal project (just to try myself) with python + tkinter. It is a encrypter, which means that it gets a piece of text and encrypts it using some famous cyphers (like the numerical cypher, the caesar's cypher, and others).
Now, I wanted to give the user the option to save the text he encrypted, and also the encrypted text generated by the program. For that, I created two checkbutton on the program's menu: one for "save text" and the other for "save encrypted text". My question is, I tried to attach a function as it's command option, so, I guess it should run that function when the option is clicked. But it isn't happening.
I'll just explain what the funcitions shouls do before passing the code.
They should prompt a question, asking the user if he/she really wants to create a text file with the text and the encrypted text (This isn't a database, it's just something for the user to be able to read later the text's he/she encrypted and the encrypted version, if he/she wants to).
So, to the code:
encryptermenu = Menu(menubar, tearoff=0)
encryptermenu.add_checkbutton(label="Save Text", variable=v, command=saveText)
encryptermenu.add_checkbutton(label="Save Encrypted Text", variable=w, command=saveEncryptedText)
menubar.add_cascade(label="Encrypter", menu=encryptermenu)
The checkbutton options, and now the functions:
def saveText():
sdtst = messagebox.askyesno(title="Save Text", message="A .txt file will be created at the same directory as this program to save the text you decided to encrypt. Is it ok?")
def saveEncryptedText():
sdtset = messagebox.askyesno(title="Save Encrypted Text", message="A .txt file will be created at the same directory as this program to save the encrypted text generated by this program. Is it ok?")
Should the checkbutton really run the function on-click or am I just making confusion?
Anyway, hope someone will help me.
Checkbutton Menu can definitely call a function. That is what the checkbutton option is there for :)
I generally use 2 functions to handle a call from the checkbutton menu.
first create that menu and assign it to a boolean var
yesno = BooleanVar(root)
mymenu.add_checkbutton(label="Do this ?", variable=yesno, command=mytoggle)
then you need 2 functions:
1) one callback to toggle
2) one to handle yes
def mytoggle(event=None):
val = yesno.get()
if val:
dosomething()
else:
somethingelse()
To answer your specific question, yes, the function will be called when you click on the checkbutton.
You should be calling add_command rather than add_checkbutton on the menu. Using a checkbutton to call a function from a menu is highly unusual and will likely confuse your users.

Categories