复选框变量未在Tkinter中更新

我对Tkinter有点陌生。我在Windows x64上运行Python 3.7.4。我正在尝试制作一个简单的复选框驱动菜单,该菜单将基于复选框传递某些值。这是代码:

main.py

import sqlite3
import os
from cryptography.fernet import Fernet

path = r"C:\Users\anves\PycharmProjects\pwdatabase\pwprotect.db"


def dbcreate():
    db = sqlite3.connect('pwprotect.db')
    csr = db.cursor()
    csr.execute("CREATE TABLE INFO(SITENAME TEXT,username TEXT,PASSWORD TEXT,PWKEY TEXT)")


if not os.path.exists(path):
    dbcreate()

db = sqlite3.connect('pwprotect.db')


def home():
    print("Welcome to Password Database!")
    print()
    print("1. Make a new entry")
    print("2. Search in existing entries")
    print("3. Update an existing entry")
    ch = int(input("Enter your choice: "))
    print()
    if ch == 1:
        insert()
    if ch == 2:
        search()
    if ch == 3:
        update()


def insert(sitename,username,password):
    while True:
        '''
        print()
        sitename = input("Enter the name of the site: ").lower()
        username = input("Enter your username for the site: ")
        password = ""
        ch = input("Do you want to use our generated password?(y/n): ")
        if ch == "y":
            password = pwgenerator()
            print("Your generated password is ",password)
        elif ch == "n":
            password = input("Enter your password for the site: ")
'''
        enk,key = encrypt(password)
        entities = (sitename,enk,key)
        cursor = db.cursor()
        cursor.execute('INSERT INTO INFO(SITENAME,username,PASSWORD,PWKEY) VALUES (?,?,?)',entities)
        db.commit()
        '''
        ch = input("Do you want to make another entry?(y/n): ")
        if ch == 'n':
            ch = input("Do you want to return to home screen?(y/n): ")
            print()
            if ch == 'y':
                home()
                break

            elif ch == 'n':
                print("Thank you for using Password Database")
                return

        elif ch == 'y':
            continue

        else:
            print("Invalid input")
            home()
            break
'''
        break
    return


def search(site):
    while True:
        # site = input('Enter the name of the site: ').lower()
        csr = db.cursor()
        csr.execute('SELECT username,PWKEY FROM INFO WHERE SITENAME == ?',(site,))
        row = csr.fetchone()
        if row is not None:
            username = row[0]
            enk = row[1]
            key = row[2]
        else:
            # print("Data not found")
            # home()
            return "not found","not found"

        password = decrypt(enk,key)
        '''
        print()
        print("username: ",username)
        print("Password: ",password)

        ch = input("Do you want to search again?(y/n): ")
        if ch == 'n':
            ch = input("Do you want to return to home screen?(y/n): ")
            print()
            if ch == 'y':
                home()
                break

            elif ch == 'n':
                print("Thank you for using Password Database")
                return

        elif ch == 'y':
            continue

        else:
            print("Invalid input")
            home()
            break
            '''
        break
    return username,password


def update(site,user,passw):
    while True:
        # site = input('Enter the name of the site: ').lower()
        # ch = int(input("1 = Change username,2 = Change Password: "))
        csr = db.cursor()
        if passw is None:
            # user = input("Enter new username: ")
            csr.execute('UPDATE INFO SET username = ? WHERE SITENAME = ?',(user,site))
            db.commit()
            # print("Your new username is ",user)

        elif site is None:
            # passw = ""
            # c = input("Do you want to use our generated password?(y/n): ")
            '''
            if c == "y":
                passw = pwgenerator()
            elif c == "n":
                passw = input("Enter new password: ")
            '''
            enk,key = encrypt(passw)

            csr.execute('UPDATE INFO SET PASSWORD = ? WHERE SITENAME = ?',(enk,site))
            csr.execute('UPDATE INFO SET PWKEY = ? WHERE SITENAME = ?',(key,site))
            db.commit()
            # print("Your new password is ",passw)

        else:
            enk,key = encrypt(passw)
            csr.execute('UPDATE INFO SET username = ? WHERE SITENAME = ?',site))
            csr.execute('UPDATE INFO SET PASSWORD = ? WHERE SITENAME = ?',site))
            db.commit()
        '''
        else:
            print("Invalid input")
            home()
            break

        ch = input("Do you want to update again?(y/n): ")

        if ch == 'n':
            ch = input("Do you want to return to home screen?(y/n): ")
            print()
            if ch == 'y':
                home()
                break

            elif ch == 'n':
                print("Thank you for using Password Database")
                return

        elif ch == 'y':
            continue

        else:
            print("Invalid input")
            home()
            break
        '''
        break


def pwgenerator():
    import random
    pw = ""
    lower = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
    upper = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
    digits = ["0","1","2","3","4","5","6","7","8","9"]
    special = ["@","%","+",'/',"!","#","$","^","?",":",",".","_","-"]
    i = 0
    while i <= 15:
        n = random.randint(0,4)
        if n == 1:
            pw = pw + random.choice(lower)
        elif n == 2:
            pw = pw + random.choice(upper)
        elif n == 3:
            pw = pw + random.choice(digits)
        elif n == 4:
            pw = pw + random.choice(special)
        i += 1
    print(pw)
    return pw


def encrypt(pw):
    key = Fernet.generate_key()
    f = Fernet(key)
    b = bytes(pw,'utf-8')
    encoded = f.encrypt(b)
    return encoded,key


def decrypt(enk,key):
    f = Fernet(key)
    decoded = f.decrypt(enk)
    pw = str(decoded.decode('utf-8'))
    return pw

gui.py

from tkinter import messagebox
import tkinter
import main

win1 = tkinter.Tk()
win1.geometry("500x200")
win1.title("Password Database")
l1 = tkinter.Label(win1,text="Welcome to Password Database!").grid(row=0,column=0)
l2 = tkinter.Label(win1,text="").grid(row=1,column=0)
entry = tkinter.Label(win1,text="1. Make a new entry")
entry.grid(row=2,column=0)
search = tkinter.Label(win1,text="2. Search for an existing entry")
search.grid(row=3,column=0)
update = tkinter.Label(win1,text="3. Update an existing entry")
update.grid(row=4,column=0)
choice = tkinter.Entry(win1,width=10)
choice.grid(row=5,column=0)


def entrygui():
    wini = tkinter.Tk()
    wini.geometry("500x200")
    wini.title("New Entry")
    entryl1 = tkinter.Label(wini,text="Enter name of the site: ")
    entryl2 = tkinter.Label(wini,text="Enter your username for the site: ")
    entryl3 = tkinter.Label(wini,text="Enter the password the site: ")
    entrye1 = tkinter.Entry(wini,width=20)
    entrye2 = tkinter.Entry(wini,width=20)
    entrye3 = tkinter.Entry(wini,width=20)
    entryl1.grid(row=0,column=0)
    entryl2.grid(row=1,column=0)
    entryl3.grid(row=2,column=0)
    entrye1.grid(row=0,column=1)
    entrye2.grid(row=1,column=1)
    entrye3.grid(row=2,column=1)

    def insertbt():
        site = str(entrye1.get())
        user = str(entrye2.get())
        passw = str(entrye3.get())
        main.insert(site,passw)
        messagebox.showinfo("Success!","Entry added!")
        wini.destroy()

    insert = tkinter.Button(wini,text="Insert",command=insertbt)
    insert.grid(row=3,column=0)

    wini.mainloop()


def searchgui():
    wins = tkinter.Tk()
    wins.geometry("500x200")
    wins.title("Search")
    searchl1 = tkinter.Label(wins,text="Enter the name of the site: ")
    searchl1.grid(row=0,column=0)
    searche1 = tkinter.Entry(wins,width=20)
    searche1.grid(row=0,column=1)

    def searchbt():
        site = str(searche1.get())
        user,passw = main.search(site)
        messagebox.showinfo("Success!","username is "+user+"\nPassword is "+passw)
        wins.destroy()

    searchbtn = tkinter.Button(wins,text="Search",command=searchbt)
    searchbtn.grid(row=1,column=0)

    wins.mainloop()


def updategui():
    winu = tkinter.Tk()
    winu.geometry("500x200")
    winu.title("Update")
    caution = tkinter.Label(winu,text="Please select the option if you are updating the corresponding value")
    caution.grid(row=0,column=0)
    sitel = tkinter.Label(winu,text="Enter site name: ")
    sitee = tkinter.Entry(winu,width=20)
    userv = tkinter.IntVar()
    userr = tkinter.Checkbutton(winu,text="New username: ",variable=userv)
    passv = tkinter.IntVar()
    passr = tkinter.Checkbutton(winu,text="New Password: ",variable=passv)
    usere = tkinter.Entry(winu,width=20)
    passe = tkinter.Entry(winu,width=20)
    sitel.grid(row=1,column=0)
    sitee.grid(row=1,column=1)
    userr.grid(row=2,column=0)
    usere.grid(row=2,column=1)
    passr.grid(row=3,column=0)
    passe.grid(row=3,column=1)

    def updatebt():
        userval = int(userv.get())
        passval = int(passv.get())
        print(userval,passval)
        site = str(sitee.get())
        if userval == 1 and passval == 0:
            user = str(usere.get())
            passw = None
            main.update(site,passw)
            messagebox.showinfo("Success","username updated")
            winu.destroy()
        elif userval == 0 and passval == 1:
            user = None
            passw = passe.get()
            main.update(site,"Password updated")
            winu.destroy()
        elif userval == 1 and passval == 1:
            user = str(usere.get())
            passw = str(usere.get())
            main.update(site,"username and password updated")
            winu.destroy()
        elif userval == 0 and passval == 0:
            messagebox.showinfo("Error","Please check a box")

    updatebtn = tkinter.Button(winu,text="Update",command=updatebt)
    updatebtn.grid(row=4,column=0)

    winu.mainloop()


def choicefn():
    ch = int(choice.get())
    if ch == 1:
        entrygui()
    elif ch == 2:
        searchgui()
    elif ch == 3:
        updategui()
    else:
        messagebox.showinfo("ERROR","Please enter a valid choice")


submit = tkinter.Button(win1,text="Submit",command=choicefn).grid(row=5,column=1)
win1.mainloop()

updategui()函数存在问题。复选框值未更新。

输出始终为0,0,并显示相应的错误框。 我编写的并行代码中没有这样的问题:

import tkinter
from tkinter import Checkbutton
win = tkinter.Tk()
v1 = tkinter.IntVar()
v1.set(0)
v2 = tkinter.IntVar()
v2.set(0)
c1 = tkinter.Checkbutton(win,text="mf",variable=v1)
c1.grid(row=0,column=0)
c2 = tkinter.Checkbutton(win,text="yeet",variable=v2)
c2.grid(row=1,column=0)
def btfn():
    i1 = (v1.get())
    i2 = (v2.get())
    print(i1,i2)
bt = tkinter.Button(win,text="Display",command=btfn)
bt.grid(row=2,column=0)
win.mainloop()

任何帮助将不胜感激! (P.S.我在变量名的末尾添加“ e”以表示Entry,在Label处添加“ l”等)

lili19890701 回答:复选框变量未在Tkinter中更新

我不是100%知道为什么会这样,但这是根据我的实验得出的最佳猜测。

IntVar的构造函数采用一个可选参数,如果提供了该参数,则应为Tk实例。如果您不提供值,它将使用首先创建的Tk。您的情况是win1对象。

每当Tk实例有机会清除其事件队列时,IntVar就会更新自身。但这是一个问题-winu窗口正在运行时,win1窗口将挂起,并且没有机会更新IntVars。

或者可能是窗口未挂起,但它只是忽略了不属于它的窗口小部件对其IntVars所做的更改。 userrpassrwinu拥有,因此win1选择不(或不能)收听它们。

一种可能的解决方案是向您的IntVar提供winu,因此默认情况下它们不会使用您的win1对象。

userv = tkinter.IntVar(winu)
userr = tkinter.Checkbutton(winu,text="New Username: ",variable=userv)
passv = tkinter.IntVar(winu)
passr = tkinter.Checkbutton(winu,text="New Password: ",variable=passv)

我找不到完全支持此功能的官方文档,但这是一个 effbot的摘录中提到通过的可能性:

  

要创建Tkinter变量,请调用相应的构造函数:

     

var = StringVar()

     

请注意,构造函数采用可选的小部件参数,但不使用值参数;要设置值,请调用set方法:

     

var = StringVar()   var.set(“ hello”)

     

仅当您在多个Tk实例上运行Tkinter时,构造函数参数才有意义(除非您真的知道自己在做什么,否则不应该这样做)。

本文链接:https://www.f2er.com/3114643.html

大家都在问