我遇到涉及登录表单的 Tkinter 应用程序问题。当我通过登录表单登录时,主 UI 没有按预期显示图像;相反,它在图像应在的位置显示一个灰色窗口。但是,如果我绕过登录并直接初始化 App 类(即不从 main 开始然后继续登录),则图像会正确加载。
# Example usage
app = App("username")
app.mainloop()
#import tkinter as tk
import ttkbootstrap as ttk
from tkinter import messagebox
from ui import App
def start_login_window():
window = ttk.Window(themename='lumen')
window.geometry('300x180')
window.title('Login')
def login():
username = inp_username.get().strip()
if username: # Add password conditions as needed
window.withdraw()
app = App(username)
app.mainloop()
window.destroy()
else:
messagebox.showerror("Login Failed", "Incorrect username or password")
lbl_username = ttk.Label(window, text='Reflex Username:')
lbl_username.pack(pady=(20, 10))
inp_username = ttk.Entry(window)
inp_username.pack()
btn_login = ttk.Button(window, text='Login', command=login)
btn_login.pack(pady=20)
window.mainloop()
#In App class display image functions:
class App(ttk.Window):
def __init__(self, username, theme='lumen'):
super().__init__(themename=theme)
self.username = username
self.title('Quality Control Application')
self.scan_state = 1 # Initialize scan_state at the beginning of the App initialization
self.scanned_data = {'SKU': None, 'GRADE': None, 'HD': None} # Ensure scanned data is also initialized
self.photo = None # Image storage
self.geometry('1700x520')
# Set window transparency: 0.0 (fully transparent) to 1.0 (fully opaque)
self.attributes('-alpha', 0.9) # Example: 90% opacity
self.db = DatabaseManager(self.username)
self.scan = ScannerWorker()
self.scan.set_on_scan_callback(self.handle_scan)
self.scan.set_display_message_callback(self.display_message)
self.scan.start()
self.initialize_ui()
self.protocol("WM_DELETE_WINDOW", self.on_close)
def initialize_ui(self):
style = ttk.Style()
# Use a style for Treeview heading
style.configure('Treeview.Heading', font=('Helvetica', 10, 'bold')) # Bold font for Treeview headers
control_frame = ttk.Frame(self)
control_frame.grid(row=0, column=0, sticky="nsew", padx=10, pady=10)
image_frame = ttk.Frame(self)
image_frame.grid(row=0, column=1, sticky="nsew", padx=10, pady=10)
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=3)
self.configure_treeview(control_frame)
self.configure_text_log(control_frame)
self.configure_image_display(image_frame)
# Add input field and update button
self.create_input_and_button(control_frame)
self.display_message("Welcome to the QC application! Please start by scanning the SKU.", color='green')
# Code to troubleshoot image not showing after login
def load_and_display_image(self, scu):
result = self.db.get_model_link_line_category(scu)
if result:
link = result[0].strip()
if link:
self.display_image(link)
else:
self.display_message_img("No image available for this SKU.")
else:
self.display_message_img("No data or image available for this SKU.")
def display_image(self, image_url):
try:
response = requests.get(image_url, verify=False) # For demonstration; disable SSL verification
if response.status_code == 200:
img_data = response.content
img = Image.open(BytesIO(img_data))
img = img.resize((360, 480)) # Resize the image if necessary
self.photo = ImageTk.PhotoImage(img) # Store the image in a PhotoImage object
# Configure the image label with the new PhotoImage object
self.image_label.config(image=self.photo)
self.image_label.image = self.photo # Maintain a reference to the PhotoImage object
else:
logging.error(f"Failed to load image. HTTP status code: {response.status_code}")
except Exception as e:
logging.error(f"Failed to load image. Error: {str(e)}")
self.display_message_img(f"Failed to load image. Error: {str(e)}")
有人可以帮助我理解为什么通过登录表单登录后图像无法加载并建议如何解决此问题吗?任何有关如何确保用户登录后正确加载图像的建议将不胜感激。
问题可能是因为
windows
函数中的 start_login_window
在 app
对象有机会完全初始化和加载图像之前被销毁。
解决该问题的一种方法是隐藏登录窗口而不是销毁它,然后在主应用程序窗口关闭后销毁它:
def start_login_window():
window = ttk.Window(themename='lumen')
window.geometry('300x180')
window.title('Login')
def login():
username = inp_username.get().strip()
if username:
window.withdraw()
app = App(username)
app.protocol("WM_DELETE_WINDOW", lambda: on_close(app, window))
app.mainloop()
# ... the rest of your code ...
def on_close(app, login_window):
app.destroy()
login_window.destroy()