tkinter不显示
代码如下:import tkinter as tkfrom tkinter import ttk
from tkinter.scrolledtext import ScrolledText
import openai
import threading
import sqlite3
from tkinter import messagebox
# 设置您的API密钥
api_key = ""
openai.api_key = api_key
class LoginRegisterGUI:
def __init__(self, root):
self.root = root
self.root.title("登录/注册")
self.root.geometry("400x200")
self.create_database()
self.login_frame = tk.Frame(root, bg="#F0F0F0")
self.login_frame.pack(fill=tk.BOTH, expand=True)
self.username_label = tk.Label(self.login_frame, text="用户名:", font=("Helvetica", 12))
self.username_label.grid(row=0, column=0, padx=5, pady=5)
self.username_entry = tk.Entry(self.login_frame, font=("Helvetica", 12))
self.username_entry.grid(row=0, column=1, padx=5, pady=5)
self.password_label = tk.Label(self.login_frame, text="密码:", font=("Helvetica", 12))
self.password_label.grid(row=1, column=0, padx=5, pady=5)
self.password_entry = tk.Entry(self.login_frame, show="*", font=("Helvetica", 12))
self.password_entry.grid(row=1, column=1, padx=5, pady=5)
self.login_button = tk.Button(self.login_frame, text="登录", font=("Helvetica", 12), command=self.login)
self.login_button.grid(row=2, column=0, columnspan=2, pady=10)
self.register_button = tk.Button(self.login_frame, text="注册新账户", font=("Helvetica", 12), command=self.register)
self.register_button.grid(row=3, column=0, columnspan=2)
def create_database(self):
# 连接到数据库(如果数据库不存在,则会创建一个新的数据库文件)
self.conn = sqlite3.connect("user_database.db")
self.cursor = self.conn.cursor()
# 创建用户表(如果不存在)
self.cursor.execute('''CREATE TABLE IF NOT EXISTS users
(id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL,
password TEXT NOT NULL)''')
def login(self):
username = self.username_entry.get().strip()
password = self.password_entry.get().strip()
if not username or not password:
messagebox.showerror("错误", "请输入用户名和密码。")
return
# 验证用户信息是否存在于数据库中
if self.verify_user(username, password):
chat_window = tk.Toplevel(self.root)
chat_gui = ChatGUI(chat_window)
else:
messagebox.showerror("错误", "用户名或密码不正确。")
def verify_user(self, username, password):
# 从数据库中查询用户信息并进行验证
self.cursor.execute("SELECT * FROM users WHERE username=? AND password=?", (username, password))
user_data = self.cursor.fetchone()
if user_data:
return True
else:
return False
def register(self):
username = self.username_entry.get().strip()
password = self.password_entry.get().strip()
if not username or not password:
messagebox.showerror("错误", "请输入用户名和密码。")
return
# 将新用户信息插入到数据库中
self.cursor.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, password))
self.conn.commit()
messagebox.showinfo("提示", "注册成功!")
class ChatGUI:
def __init__(self, root):
self.root = root
self.root.title("ChatGPT-3.5")
self.root.geometry("600x400")
self.chat_frame = tk.Frame(root, bg="#F0F0F0")
self.chat_frame.pack(fill=tk.BOTH, expand=True)
self.chat_canvas = tk.Canvas(self.chat_frame, bg="#F0F0F0", highlightthickness=0)
self.chat_canvas.pack(pady=5, padx=5, fill=tk.BOTH, expand=True)
self.vsb = ttk.Scrollbar(self.chat_frame, orient="vertical", command=self.chat_canvas.yview)
self.vsb.pack(side="right", fill="y")
self.chat_canvas.configure(yscrollcommand=self.vsb.set)
self.chat_canvas.bind("<Configure>", self.on_frame_configure)
self.chat_canvas.bind_all("<MouseWheel>", self.on_mousewheel)
self.chat_window = self.chat_canvas.create_window((0, 0), window=self.chat_frame, anchor=tk.NW)
self.create_widgets()
self.message_list = []
self.waiting_label = None
# 在这里添加一个延迟,以便让聊天界面能够显示
self.root.after(100, self.show_chat_window)
def show_chat_window(self):
print("显示聊天界面")
self.chat_canvas.pack(fill=tk.BOTH, expand=True)
print("聊天界面显示完成")
def on_frame_configure(self, event):
self.chat_canvas.configure(scrollregion=self.chat_canvas.bbox("all"))
def on_mousewheel(self, event):
self.chat_canvas.yview_scroll(-1 * (event.delta // 120), "units")
def create_widgets(self):
self.input_text = ScrolledText(self.chat_frame, height=4, wrap=tk.WORD, font=("Helvetica", 12))
self.input_text.pack(pady=10, padx=10, fill=tk.X)
self.send_button = tk.Button(self.chat_frame, text="发送", font=("Helvetica", 12), command=self.send_message)
self.send_button.pack(pady=5)
def send_message(self):
user_input = self.input_text.get("1.0", tk.END).strip()
if user_input.lower() == 'exit':
self.root.quit()
return
# 显示等待动画
if self.waiting_label:
self.waiting_label.pack_forget()
self.waiting_label = tk.Label(self.chat_frame, text="等待回复中...", bg="#F0F0F0")
self.waiting_label.pack()
self.root.update()
# 启动线程来处理消息
message_thread = threading.Thread(target=self.process_message, args=(user_input,))
message_thread.start()
def process_message(self, user_input):
try:
# 处理消息并显示回复
response = self.chat_with_gpt3(user_input)
# 清除等待动画
self.waiting_label.pack_forget()
self.add_message("您: " + user_input, True)# 用户消息
self.add_message("ChatGPT-3.5: " + response, False)# 机器助手消息
self.input_text.delete("1.0", tk.END)
except Exception as e:
print("Error:", e)
def add_message(self, message_text, is_user):
bg_color = "#E7F5E9" if is_user else "#DDEBF7"
text_color = "black" if is_user else "black"
x = 10 if is_user else 60
align = tk.W if is_user else tk.E
message_label = tk.Label(
self.chat_frame, text=message_text, font=("Helvetica", 12), wraplength=400,
bg=bg_color, padx=10, pady=5, anchor=align, justify=tk.LEFT, fg=text_color
)
self.message_list.append(message_label)
self.chat_canvas.create_window((x, len(self.message_list) * 70), window=message_label, anchor=tk.NW)
def chat_with_gpt3(self, prompt):
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",# 使用ChatGPT-3.5 Turbo模型
messages=[
{"role": "system", "content": "您是一个有用的助手。"},
{"role": "user", "content": prompt}
]
)
return response['choices']['message']['content']
if __name__ == "__main__":
root = tk.Tk()
login_gui = LoginRegisterGUI(root)
root.mainloop()
问题如下:
怎么办?! 没添加更新函数吧{:301_1000:} 这可能是因为在ChatGUI类中,create_widgets()方法里创建了输入框和发送按钮,但是这些部件是packing到chat_frame上的。
而chat_frame 是嵌入在chat_canvas的一个窗口中,默认情况下一开始是不可见的。
代码里通过root.after(100, self.show_chat_window)延迟了一段时间后再显示chat_canvas,所以一开始看不到输入框和按钮。
可以调整一下延迟的时间,或者直接在__init__方法最后调用self.show_chat_window(),应该就能立即看到输入框和按钮了。
另外也可以考虑直接把输入框和按钮packing到chat_canvas上,而不是chat_frame,这样应该也能立即显示出来。 用PyCharm的debugger工具,逐行运行过去试试 没看出来,不过我建议先用布局工具写好页面,再给控件绑定事件。在线布局工具我之前使用的是这个(拖拽控件布局,最后再下载源码):https://www.pytk.net/tkinter-helper/
页:
[1]