【问题标题】:tkinter: how to detect `Checkbutton` when GUI starts?tkinter:GUI启动时如何检测“Checkbutton”?
【发布时间】:2021-08-16 18:46:42
【问题描述】:

我的问题是: 我创建了一个Entry 窗口来放置用户的登录信息。然后我创建了Checkbutton 来记住登录。

我的代码在以下情况下有效:

  1. 我输入登录名
  2. 勾选框(更具体:取消勾选并再次勾选,因为当不这样做时它不会保存登录。这是我的问题的一部分)
  3. 退出 GUI
  4. 当我再次打开 GUI 时,会显示登录信息。 问题是:
  5. 当我再次打开 GUI 时,没有显示登录信息 - 它应该是 - 即使选中了 Checkbutton(默认情况下)。

我假设问题是:我的代码没有检测到Checkbutton 的初始状态。 我正在寻找解决方案:如何强制我的代码以与用户物理单击/勾选(或取消勾选)相同的方式检测Checkbutton 的初始状态?

我的代码:

import os
import tkinter as tk
import tkinter.font as font

#global root
root = tk.Tk()
root.geometry("1740x850")
root.columnconfigure(0, weight=3)
root.rowconfigure(0, weight=3)
# https://stackoverflow.com/questions/51591456/can-i-use-rgb-in-tkinter/51592104
def from_rgb(rgb):
    """translates an rgb tuple of int to a tkinter friendly color code
    """
    return "#%02x%02x%02x" % rgb   

root.title('Reproducible Example')

content = tk.Frame(root)
content.configure(bg='LightCyan2')

content.columnconfigure(0, weight=8)
content.columnconfigure(1, weight=8)
content.columnconfigure(2, weight=8)
content.columnconfigure(3, weight=8)
content.columnconfigure(4, weight=8)

content.rowconfigure(0, weight=8)
content.rowconfigure(1, weight=8)
content.rowconfigure(2, weight=8)
content.rowconfigure(3, weight=8)
content.rowconfigure(4, weight=8)
content.rowconfigure(5, weight=8)
content.rowconfigure(6, weight=8)
content.rowconfigure(7, weight=8)
content.rowconfigure(8, weight=8)
content.rowconfigure(9, weight=8)



# =============================================================================
# Button's font pattern:
# =============================================================================
font_button_big = font.Font(family='Helvetica', size="11", weight='bold')
font_button_small = font.Font(family='Helvetica', size="10", weight='bold')

# =============================================================================
# creating a window that will allow a user to place account_login login
# =============================================================================
label_entry_account_login_login = tk.Label(
        content, text="account_login Name: ",
        width=18,
        bg=from_rgb((193,254,252)),
        font=font_button_big,
        anchor="e"
        )
#L1.pack(side = tk.LEFT)
# This line allows to display text in entry: `entry_account_login_login' from txt file: 'Offer List, Clients, logins\account_login_login.txt'
account_login_login_var=tk.StringVar()

entry_account_login_login = tk.Entry(
        content,
        textvariable=account_login_login_var,
        bd =5,
        width=40
        )
#entry_account_login_login.pack()
text_account_login_name = entry_account_login_login.get()

# account_login checkbutton: `remeber login`

# load the text before startup
# https://stackoverflow.com/questions/41979656/is-it-possible-to-make-tkinter-remember-variables-when-you-close-it
if os.path.isfile(r'Offer List, Clients, logins\account_login_login.txt'):
    with open(r'Offer List, Clients, logins\account_login_login.txt') as text_file_account_login_login:
        account_login_login_var.set(text_file_account_login_login.read())

def account_login_login_remember():
    if account_login_login_remembervar.get() == True:
        text_account_login_name = entry_account_login_login.get()
        print("text_account_login_name(true mode): ", bool(text_account_login_name)) # test
        # https://www.codegrepper.com/code-examples/python/python+save+input+to+text+file
        with open(r'Offer List, Clients, logins\account_login_login.txt', "w") as text_file_account_login_login:
        #Opens or creates the .txt file, sharing the directory of the script
            text_file_account_login_login.write(text_account_login_name) # Writes the variable into the .txt file # text_account_login_name
            text_file_account_login_login.close() # Closes the .txt file

account_login_login_remembervar = tk.BooleanVar(value=True)

account_login_bt_login_remeber = tk.Checkbutton(
        content,
        text="remeber login",
        variable=account_login_login_remembervar,
        onvalue=True,
        bg=from_rgb((193,254,252)),
        font=font_button_big,
        command=account_login_login_remember
        )

# =============================================================================
# creating a window that will allow a user to place account_login pass
# =============================================================================

label_entry_account_login_pass = tk.Label(
        content, text="account_login pass: ",
        width=18,
        bg=from_rgb((193,254,252)),
        font=font_button_big,
        anchor="e"
        )
#L2.pack(side = tk.LEFT)

# https://stackoverflow.com/questions/10989819/hiding-password-entry-input-in-python:
entry_account_login_pass = tk.Entry(content, bd =5, width=40, show="*")
#entry_account_login_pass.pack()
text_account_login_pass = entry_account_login_pass.get()
# =============================================================================
# making "exit window" button
# =============================================================================

exit_button = tk.Button(content, 
          text='Quit', 
          command=content.quit)
# =============================================================================
# Main grid:
# =============================================================================

content.grid(column=0, row=0)
#frame.grid(column=0, row=0, columnspan=3, rowspan=6)

exit_button.grid(column=2, row=9)

label_entry_account_login_login.grid(column=1, row=1,  sticky=(tk.N))
entry_account_login_login.grid(column=2, row=1, sticky=(tk.N), rowspan=3)
account_login_bt_login_remeber.grid(column=3, row=1,  sticky=(tk.N))
label_entry_account_login_pass.grid(column=1, row=2, sticky=(tk.N))
entry_account_login_pass.grid(column=2, row=2, sticky=(tk.N), rowspan=3)




with open(r'Offer List, Clients, logins\account_login_login.txt','w') as text_file_account_login_login:
    text_file_account_login_login.write(text_account_login_name)
    

root.mainloop()

text_file_account_login_login.close() # Closes the .txt file

【问题讨论】:

  • 检查代码开头的account_login_remembervar是什么值? (这也需要将其移到顶部),如果您提供 minimal reproducible example 也很好,我不太明白您的意思 登录不显示跨度>
  • 您好,我刚刚更新了我的代码。现在提供了最小的可重现示例。唯一的事情是:需要在某处创建一个文本文件。我的路径是:C:\Users\b2b\Desktop\My projects\Offer List, Clients, logins\account_login_login.txt。需要文件account_login_login.txt 来保存登录。如果你的电脑上没有它,就无法检查我的代码。
  • 我没有看到任何minimal reproducible example,而且您仍然没有解释未显示登录名是什么意思。无论如何,据我了解,您想保存检查按钮状态并在下次程序启动时以该状态加载它?
  • 似乎不是最小,是吗?所以再次minimal reproducible example 将不胜感激,但您到底想实现什么?下次保存并加载按钮状态?
  • 最小的可重现示例是我第一篇文章中的更新代码。我还在这里发布了一个视频来解释核心问题是什么:youtube.com/watch?v=whcQtyfL0No

标签: python tkinter


【解决方案1】:

这是通常的方法,保存用户数据以供登录时记住:

from tkinter import Tk, Frame, Label, Entry, Button, Checkbutton, BooleanVar


# open file and read it, if previously checked to remember then the first line
# will contain the name, else it will be empty
with open('myfile.txt') as file:
    name = file.readline()


def sign_in():
    # get data from entry
    data = entry.get()
    with open('myfile.txt', 'w') as f:  # open file in write mode
        f.write(data if var.get() else '')  # if user wanted to remember then write to file
        # the entered data else write nothing (note that this will overwrite everything in the file)
    # the login code but in this case just quit
    root.quit()  # or use `exit()` depending on what you need


root = Tk()

frame = Frame(root)
frame.pack()

Label(frame, text='Name:').pack(side='left')

# define entry and insert the saved name if there is a saved name
entry = Entry(frame)
entry.insert(0, name)
entry.pack(side='left')

var = BooleanVar(value=1)
Checkbutton(frame, text='Remember', variable=var).pack(side='right')

Button(root, text='Sign In', command=sign_in).pack()

root.mainloop()

如果您想在窗口关闭时保存数据而不必按任何操作,您可以这样做:

from tkinter import Tk, Frame, Label, Entry, Button, Checkbutton, BooleanVar


# open file and read it, if previously checked to remember then the first line
# will contain the name, else it will be empty
with open('myfile.txt') as file:
    name = file.readline()


def save_data():
    # get data from entry
    data = entry.get()
    with open('myfile.txt', 'w') as f:  # open file in write mode
        f.write(data if var.get() else '')  # if user wanted to remember then write to file
        # the entered data else write nothing (note that this will overwrite everything in the file)
    root.quit()  # or use `exit()` depending on what you need


root = Tk()
root.protocol('WM_DELETE_WINDOW', save_data) # this protocol
# is triggered when user presses the "X" button in the top right corner of window

Label(root, text='Name:').pack(side='left')

# define entry and insert the saved name if there is a saved name
entry = Entry(root)
entry.insert(0, name)
entry.pack(side='left')

var = BooleanVar(value=1)
Checkbutton(root, text='Remember', variable=var).pack(side='right')

root.mainloop()

解释在代码 cmets 但如果您有任何问题,请询问他们!

【讨论】:

  • 谢谢。你的第二种方法是完美的。稍作修改后,效果很好。
猜你喜欢
  • 2011-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-19
  • 2022-12-09
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
相关资源
最近更新 更多