tkinter实现chatGPT对话深色界面

chatGPT官网经常会因为系统升级等情况而不能用, 有时候响应也特别慢, 于是API排上用场. 

之前写了一个简易的命令窗式的问答, 能多轮对话, 还能保存对话, 但是输入很不方便. 

 回头一看额度才用了4毛钱, 于是在api免费期限还剩一个一个月的时候写了一个对话界面, 目前只是单轮对话,后期将加入更多功能, 尽最大努力用完剩下余额. 

API接口

首先是chatGPT的接口, 这个网上例程很多, 主要是返回消息和所耗费的taken.

import os
import openai
import json
# from main_window import *
if os.getenv('chatgpt_key'):
    openai.api_key = os.getenv('chatgpt_key')
else:
    openai.api_key_path = "E:\chatgpt\key.txt"


def connect(message):
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=message
    )

    message = response["choices"][0]["message"]
    token = int(response["usage"]["total_tokens"])
    return token, message

主界面

主界面采用tkinter, 利用chatGPT先生成一个简单示例, 然后在此基础上不断优化界面, 在不拥专门学习这个库的情况下就能写出外观不错的界面, 可以很容易修改输入内容. 同时能够显示对话耗费了多少taken, 换算的多少刀.

 

代码如下, 没太注意格式风格, 只为快速迭代

import tkinter as tk

import time
import threading
import uChat_0.coreChat as core

class DarkChatGUI():
    def __init__(self, title="Chat"):
        self.title = title
        self.message_user = ''
        self.taken = 0
        self.total_taken = 0
        self.cost = 0
        self.info = ''
        font = 'Consolas'

        # 创建主窗口
        self.root = tk.Tk()
        self.root.title(self.title)
        self.root.configure(bg="black")
        self.root.geometry("700x580")
        # self.root.overrideredirect(True)    # 使窗口没有边框和标题栏

        # 创建聊天显示框
        self.display_frame = tk.Frame(self.root, bg="#262626")    # #262626 black
        self.display_frame.pack(side="top", fill="both", expand=True)
        self.chat_display = tk.Text(self.display_frame, bg="#2f2f2f", fg="white", wrap="word", state="disabled",
                                    font=(font, 12))
        self.chat_display.pack(side="top", fill="both", expand=True, padx=8, pady=8)
        # 聊天显示样式设置
        self.chat_display.tag_configure('user_name', background="red", font=(font, 12, 'bold'))
        self.chat_display.tag_configure('ai_name', background="green", font=(font, 12, 'bold'))
        self.chat_display.tag_configure('user_text', spacing1=10, spacing2=8, foreground='#D6D6D6')
        self.chat_display.tag_configure('ai_text', spacing1=10, spacing2=8, foreground='#D6D6D6')
        self.chat_display.tag_configure('info', foreground='orange', font=(font, 11, 'bold'))

        # 创建信息输入框
        self.input_frame = tk.Frame(self.root, bg="#262626")
        self.input_frame.pack(side="bottom", fill="both", expand=False, padx=3, pady=3)
        self.message_entry = tk.Text(self.input_frame, height=10, spacing3=10, bg="#2f2f2f",
                                     fg="white", font=(font, 11), insertbackground='white')
        self.message_entry.pack(side="left", fill="both", expand=True)
        self.message_entry.tag_configure('text', spacing2=6, foreground='white')
        # 发送按键
        self.send_button = tk.Button(self.input_frame, text="Send", bg="#3860C0", fg="white",
                                     font=(font, 12, 'bold'), command=self.send_message)
        self.send_button.pack(side="left", fill="both")

        # 监听 Enter 键
        self.root.bind('<Control-Return>', self.send_message)


    def send_message(self, event=None):
        self.message_user = self.message_entry.get('0.0', "end").strip()
        if self.message_user:
            # cut_line = '\t '*7 + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

            self.message_entry.delete('0.0', "end")
            self.chat_display.configure(state="normal")
            self.chat_display.insert("end", ' 我:\t', 'user_name')
            print(self.info)
            cut_line = '\n' + '--' * 40 + ''
            self.chat_display.insert("end", cut_line, 'info')
            self.chat_display.insert("end", '\n' + self.message_user + "\n\n", "user_text")
            # 弹出提示框
            self.chat_display.insert("end",
                                     "\n\t\t\t---------- 等待AI回应 ---------\n", 'info')
            # self.chat_display.configure(state="disabled")
            self.chat_display.see(tk.END)

            t = threading.Thread(target=self.receive_message, args=())
            t.start()
            # self.receive_message()

    def receive_message(self):
        send_message = [{"role": "user", "content": self.message_user}]
        self.taken, message_r = core.connect(send_message)
        message = message_r['content']
        self.comp_taken()
        if message:
            # print(message)
            self.chat_display.delete("end-2l", tk.END)
            self.chat_display.configure(state="normal")
            self.chat_display.insert("end", ' ChatGPT:\t', 'ai_name')
            self.chat_display.insert("end", self.info, 'info')

            self.chat_display.insert("end", '\n' + message + "\n\n", "ai_text")
            self.chat_display.configure(state="disabled")
            self.chat_display.see(tk.END)

    def start(self):
        self.root.mainloop()

    def comp_taken(self):
        self.total_taken += self.taken
        self.cost  = self.total_taken * 0.002/1000
        self.info = '\t\tpast: ' + str(self.taken) + \
               '\t\ttotal: ' + str(self.total_taken) + \
               '\t\tcost: $' + str(round(self.cost, 4))

if __name__ == "__main__":
    gui = DarkChatGUI()
    gui.start()

后续有空了再加人更多功能, 例如对本地数据库文献库的管理, 还可以结合单机的本地模型. 实现高效学习和工作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值