如何在CustomTkinter中实现发送消息后滚动条自动滚到底部
CustomTkinter 聊天框自动滚动到底部解决方案
CTkScrollableFrame 内部封装了 Canvas 和滚动条组件,不需要套用常规 Tkinter Canvas 的方案,直接操作其内部的 Canvas 即可实现发送消息后自动滚到底部的效果。
修改发送消息函数
在 Send_Message 函数末尾添加两行关键代码,确保新消息添加后滚动条自动定位到底部:
def Send_Message(): # Button send function message = entry.get() # Create a message bubble frame bubble_frame = ctk.CTkFrame(frame, width=250, corner_radius=20, fg_color="lightblue") bubble_frame.pack(anchor="e", padx=10, pady=5) # Adjust the padx and pady values as needed # Create a label inside the bubble frame label = ctk.CTkLabel(bubble_frame, text_color="Black", text=message, font=("Helvetica", 14), bg_color="lightblue") label.pack(expand=True, fill="both", padx=10, pady=5) entry.delete(0, "end") # 自动滚动到底部的核心代码 root.update_idletasks() # 立即更新界面,确保新消息的尺寸被正确计算 frame._canvas.yview_moveto(1.0) # 将垂直滚动位置设置为最底部(1.0 代表100%)
代码说明
root.update_idletasks():强制 Tkinter 处理所有待完成的界面渲染任务,确保新添加的消息气泡高度被准确计算,避免滚动操作因尺寸未更新而失效。frame._canvas:CTkScrollableFrame 内部的 Canvas 实例,通过它可以直接调用 Tkinter Canvas 的滚动方法。yview_moveto(1.0)是 Canvas 的标准方法,将垂直滚动条直接定位到最底部。
完整修改后代码
from tkinter import * import customtkinter as ctk import tkinter as tk from PIL import Image, ImageTk # Window root = ctk.CTk() root.geometry("350x500") root.title("v2") root.resizable(False, False) ctk.set_appearance_mode("Light") send_image_original = Image.open("send-message.png") # Adding and resizing image for button send_resize = send_image_original.resize((50, 50)) send_image = ImageTk.PhotoImage(send_resize) def Send_Message(): # Button send function message = entry.get() # Create a message bubble frame bubble_frame = ctk.CTkFrame(frame, width=250, corner_radius=20, fg_color="lightblue") bubble_frame.pack(anchor="e", padx=10, pady=5) # Adjust the padx and pady values as needed # Create a label inside the bubble frame label = ctk.CTkLabel(bubble_frame, text_color="Black", text=message, font=("Helvetica", 14), bg_color="lightblue") label.pack(expand=True, fill="both", padx=10, pady=5) entry.delete(0, "end") # 自动滚动到底部 root.update_idletasks() frame._canvas.yview_moveto(1.0) send = ctk.CTkButton(master=root, corner_radius=10, command=Send_Message, image=send_image, text="", fg_color="Blue", width=30, height=40) send.place(relx=0.8, rely=0.9, anchor=tk.CENTER) frame = ctk.CTkScrollableFrame(master=root, width=300, height=350, corner_radius=10, fg_color="White") frame.place(relx=0.5, rely=0.43, anchor=tk.CENTER) entry = ctk.CTkEntry(master=root, width=200, height=50, corner_radius=10) entry.place(relx=0.4, rely=0.9, anchor=tk.CENTER) def on_enter_key(event): Send_Message() entry.bind("<Return>", on_enter_key) root.mainloop()
内容的提问来源于stack exchange,提问作者Wali Lambert
相关产品推荐
相关产品推荐

