如何基于SQL数据动态生成含复杂逻辑的CTkButton及关联函数?
Fix the MySQL "Unread Result Found" Error
This error occurs when you leave unconsumed results in your cursor before running a new query. Fix it with either of these approaches:
- Use a buffered cursor when initializing:
cursor = conn.cursor(buffered=True) - Always fetch all results after executing a query:
cursor.execute("SELECT id, _name, _cost, _price, _category FROM items") items = cursor.fetchall() # Consumes all results to clear the cursor
Dynamic Command Generation Without exec
Instead of generating named methods like generatebuttoncommand{N}, use closures to create item-specific callbacks. This avoids messy string-based code generation and scales cleanly.
Step 1: Create a Command Factory Method
Add this method to your customtkinter class to generate callbacks bound to each item's data:
def create_item_callback(self, item_data): item_id, name, cost, price, category = item_data def show_details_and_update(): # Create a toplevel window to display item details details_window = customtkinter.CTkToplevel(self) details_window.title(f"{name} Details") # Display item fields customtkinter.CTkLabel(details_window, text=f"Name: {name}").pack(pady=4) customtkinter.CTkLabel(details_window, text=f"Cost: ${cost:.2f}").pack(pady=4) customtkinter.CTkLabel(details_window, text=f"Price: ${price:.2f}").pack(pady=4) customtkinter.CTkLabel(details_window, text=f"Category: {category}").pack(pady=4) # Add input fields for updates (customize as needed) new_cost_entry = customtkinter.CTkEntry(details_window, placeholder_text="New Cost") new_cost_entry.pack(pady=6) new_price_entry = customtkinter.CTkEntry(details_window, placeholder_text="New Price") new_price_entry.pack(pady=6) # Update database function def update_item_in_db(): try: new_cost = float(new_cost_entry.get()) new_price = float(new_price_entry.get()) update_query = """ UPDATE items SET _cost = %s, _price = %s WHERE id = %s """ self.cursor.execute(update_query, (new_cost, new_price, item_id)) self.conn.commit() details_window.destroy() self.refresh_items() # Refresh buttons after update except ValueError: # Handle invalid input (e.g., show error label) pass # Add update button customtkinter.CTkButton( details_window, text="Save Changes", command=update_item_in_db ).pack(pady=10) return show_details_and_update
Step 2: Auto-Generate Buttons from SQL Data
Create a method to load items from the database and generate corresponding CTkButtons:
def refresh_items(self): # Clear existing buttons to avoid duplicates for widget in self.item_button_frame.winfo_children(): widget.destroy() # Fetch latest items from DB self.cursor.execute("SELECT id, _name, _cost, _price, _category FROM items") items = self.cursor.fetchall() # Create a button for each item for item in items: item_name = item[1] item_btn = customtkinter.CTkButton( self.item_button_frame, text=item_name, command=self.create_item_callback(item) ) item_btn.pack(pady=5, fill="x")
Handle New Database Entries
- After inserting a new item into the
itemstable, callself.refresh_items()to immediately generate a button for the new entry. - Optionally, add a "Refresh Items" button in your UI that triggers
refresh_items()for manual updates.
内容的提问来源于stack exchange,提问作者Pavlos Katsioulis
相关产品推荐
相关产品推荐

