import requests
from typing import Optional, Dict, Any
class GPTClient:
def __init__(self, api_key: str = None, api_url: str = None):
from database import db
self.api_key = api_key or db.get_setting('api_key') or ""
self.api_url = api_url or db.get_setting('api_url') or "https://api.openai.com/v1/chat/completions"
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
})
def ask_question(self, question: str, code_context: Optional[str] = None, callback=None) -> Optional[str]:
if not self.api_key:
return "错误:请先设置 API 密钥"
messages = []
if code_context:
messages.append({
"role": "system",
"content": f"以下是相关代码上下文:\n```python\n{code_context}\n```\n请基于此代码上下文回答问题。"
})
messages.append({"role": "user", "content": question})
data = {
"model": "gpt-3.5-turbo",
"messages": messages,
"max_tokens": 1000,
"temperature": 0.7,
"stream": False
}
try:
response = self.session.post(self.api_url, json=data, timeout=30)
if response.status_code == 200:
result = response.json()
return result['choices'][0]['message']['content']
else:
return f"API 错误:{response.status_code}"
except Exception as e:
return f"请求错误:{str(e)}"
import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
class CodeEditor(tk.Frame):
def __init__(self, parent, **kwargs):
super().__init__(parent, **kwargs)
self.create_widgets()
def create_widgets(self):
toolbar = tk.Frame(self)
toolbar.pack(fill=tk.X, padx=5, pady=2)
tk.Button(toolbar, text="新建", command=self.new_file, width=6).pack(side=tk.LEFT, padx=2)
tk.Button(toolbar, text="保存", command=self.save_file, width=6).pack(side=tk.LEFT, padx=2)
self.text_widget = scrolledtext.ScrolledText(
self, wrap=tk.WORD, font=("Consolas", 12),
bg="#f8f8f8", fg="#333333"
)
self.text_widget.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
def get_code(self):
return self.text_widget.get(1.0, tk.END).strip()
class GPTAssistant(tk.Frame):
def __init__(self, parent, code_editor, **kwargs):
super().__init__(parent, **kwargs)
self.code_editor = code_editor
self.create_widgets()
def create_widgets(self):
tk.Label(self, text="问题:", font=("Arial", 10, "bold")).pack(anchor=tk.W, padx=10, pady=(10, 0))
self.question_text = scrolledtext.ScrolledText(self, height=8, wrap=tk.WORD)
self.question_text.pack(fill=tk.X, padx=10, pady=5)
button_frame = tk.Frame(self)
button_frame.pack(fill=tk.X, padx=10, pady=10)
self.ask_button = tk.Button(
button_frame, text="获取答案", command=self.ask_gpt,
bg="#007acc", fg="white", font=("Arial", 11, "bold")
)
self.ask_button.pack(side=tk.LEFT, padx=5)
self.notebook = ttk.Notebook(self)
self.notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
answer_frame = tk.Frame(self.notebook)
self.notebook.add(answer_frame, text="答案")
self.answer_text = scrolledtext.ScrolledText(answer_frame, wrap=tk.WORD)
self.answer_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
def ask_gpt(self):
question = self.question_text.get(1.0, tk.END).strip()
if not question:
messagebox.showwarning("警告", "请输入问题")
return
code_context = self.code_editor.get_code()
self.ask_button.config(state=tk.DISABLED, text="处理中...")
from gpt_client import gpt_client
answer = gpt_client.ask_question(question, code_context)
self.answer_text.delete(1.0, tk.END)
self.answer_text.insert(1.0, answer)
self.ask_button.config(state=tk.NORMAL, text="获取答案")