You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter登录表单密码切换报错:PhotoImage无configure属性

解决Tkinter点击眼睛图标切换密码显示时的AttributeError问题

问题概述

使用PyCharm开发Python登录表单,需求是点击眼睛图标切换密码的显示/隐藏状态,同时切换图标样式。程序可正常启动,但点击眼睛按钮时触发报错:

AttributeError: type object 'PhotoImage' has no attribute 'configure'

错误原因分析

  1. 变量名错误:hide函数中使用了未定义的open_eye_image变量,实际代码中定义的图片变量是open_image。
  2. API使用错误:PhotoImage对象本身没有configure方法,无法直接修改其属性。要切换按钮图标,需通过按钮组件的configure方法修改image参数。
  3. 功能缺失:原代码未实现密码显示/隐藏的核心逻辑,仅尝试修改图标。
  4. 潜在图片回收问题:Tkinter的PhotoImage若未被持续引用,会被Python垃圾回收机制回收,导致图标消失。

修复步骤

  1. 定义双图标对象:分别创建睁眼、闭眼两种状态的PhotoImage实例,用于切换显示。
  2. 完善切换逻辑:在切换函数中,通过按钮的configure方法替换图标,同时修改密码输入框的show属性控制密码显示。
  3. 保留图片引用:将图片对象绑定到按钮或窗口属性上,避免被垃圾回收。
  4. 优化导入语句:移除重复的PhotoImage导入,简化代码结构。

修正后的完整代码

import tkinter
from tkinter import messagebox, END
import pypyodbc as odbc
from PIL import ImageTk

# GUI初始化
window = tkinter.Tk()
window.resizable(0, 0)
window.title("Database Login")
window.geometry('990x660+50+50')
bg_Image = ImageTk.PhotoImage(file='whew.jpg')

# 全局状态标记:记录当前密码是否隐藏
is_password_hidden = True

# 输入框焦点事件处理
def user_enter(event):
    if usernameEntry.get() == 'Username':
        usernameEntry.delete(0, END)

def pass_enter(event):
    if passwordEntry.get() == 'Password':
        passwordEntry.delete(0, END)

# 密码显示/隐藏切换函数
def toggle_password_visibility():
    global is_password_hidden
    if is_password_hidden:
        # 切换为显示密码,图标换成闭眼
        passwordEntry.configure(show='')
        eyeButton.configure(image=close_image)
        is_password_hidden = False
    else:
        # 切换为隐藏密码,图标换成睁眼
        passwordEntry.configure(show='*')
        eyeButton.configure(image=open_image)
        is_password_hidden = True

# 创建组件
bgLabel = tkinter.Label(window, image=bg_Image)
heading = tkinter.Label(window, text='USER LOGIN', bg='white',  fg='#FF81C0', font=('Microsoft Yahei UI Light', 23))
usernameEntry = tkinter.Entry(window, width=25, font=('Microsoft Yahei UI Light', 11), bd=0, fg='#FF81C0')
# 初始化密码框为隐藏状态
passwordEntry = tkinter.Entry(window, width=25, font=('Microsoft Yahei UI Light', 11), bd=0, fg='#FF81C0', show='*')

# 加载图标图片,并绑定到按钮属性避免被回收
open_image = ImageTk.PhotoImage(file='openeyeeeee fr (1).png')
close_image = ImageTk.PhotoImage(file='closeyeeeeee fr.png')

eyeButton = tkinter.Button(window, image=open_image, bd=0, bg='white', activebackground='white', cursor='hand2', command=toggle_password_visibility)
# 保留图片引用,防止被垃圾回收
eyeButton.open_image = open_image
eyeButton.close_image = close_image

# 布局组件
bgLabel.place(x=0, y=0)
heading.place(x=630, y=200)
usernameEntry.place(x=620, y=300)
passwordEntry.place(x=620, y=350)

usernameEntry.insert(0, 'Username')
passwordEntry.insert(0, 'Password')

usernameEntry.bind('<FocusIn>', user_enter)
passwordEntry.bind('<FocusIn>', pass_enter)

# 输入框下划线
tkinter.Frame(window, width=215, height=2, bg='#FF81C0').place(x=620, y=320)
tkinter.Frame(window, width=215, height=2, bg='#FF81C0').place(x=620, y=370)

eyeButton.place(x=810, y=345)

window.mainloop()

关键修改说明

  • 状态标记:新增is_password_hidden变量记录当前密码显示状态,用于判断切换方向。
  • 切换逻辑:toggle_password_visibility函数中,通过passwordEntry.configure(show='')显示密码,show='*'隐藏密码;同时通过eyeButton.configure(image=...)切换按钮图标。
  • 图片引用:将open_image和close_image绑定到eyeButton的属性上,防止Python垃圾回收机制回收图片对象导致图标消失。
  • 变量名修正:移除了未定义的open_eye_image变量,使用正确的图片对象进行操作。

内容的提问来源于stack exchange,提问作者alexus glass

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 15:00:54