一個賬號 发表于 2023-7-22 14:43

tkinter不显示

代码如下:import tkinter as tk
from 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()


问题如下:



怎么办?!

yuyanjing 发表于 2023-7-22 15:07

没添加更新函数吧{:301_1000:}

当初遇你时 发表于 2023-7-22 17:38

这可能是因为在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,这样应该也能立即显示出来。

hrh123 发表于 2023-7-22 18:08

用PyCharm的debugger工具,逐行运行过去试试

stanfork 发表于 2023-7-22 19:16

没看出来,不过我建议先用布局工具写好页面,再给控件绑定事件。在线布局工具我之前使用的是这个(拖拽控件布局,最后再下载源码):https://www.pytk.net/tkinter-helper/
页: [1]
查看完整版本: tkinter不显示