+48
-7
@@ -120,18 +120,59 @@ class OllamaEmbeddingAdapter(BaseEmbeddingAdapter):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
class MLStudioEmbeddingAdapter(BaseEmbeddingAdapter):
|
class MLStudioEmbeddingAdapter(BaseEmbeddingAdapter):
|
||||||
|
"""
|
||||||
|
基于 LM Studio 的 embedding 适配器
|
||||||
|
"""
|
||||||
def __init__(self, api_key: str, base_url: str, model_name: str):
|
def __init__(self, api_key: str, base_url: str, model_name: str):
|
||||||
self._embedding = OpenAIEmbeddings(
|
self.url = ensure_openai_base_url_has_v1(base_url)
|
||||||
openai_api_key=api_key,
|
if not self.url.endswith('/embeddings'):
|
||||||
openai_api_base=ensure_openai_base_url_has_v1(base_url),
|
self.url = f"{self.url}/embeddings"
|
||||||
model=model_name
|
|
||||||
)
|
self.headers = {
|
||||||
|
"Authorization": f"Bearer {api_key}",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
self.model_name = model_name
|
||||||
|
|
||||||
def embed_documents(self, texts: List[str]) -> List[List[float]]:
|
def embed_documents(self, texts: List[str]) -> List[List[float]]:
|
||||||
return self._embedding.embed_documents(texts)
|
try:
|
||||||
|
payload = {
|
||||||
|
"input": texts,
|
||||||
|
"model": self.model_name
|
||||||
|
}
|
||||||
|
response = requests.post(self.url, json=payload, headers=self.headers)
|
||||||
|
response.raise_for_status()
|
||||||
|
result = response.json()
|
||||||
|
if "data" not in result:
|
||||||
|
logging.error(f"Invalid response format from LM Studio API: {result}")
|
||||||
|
return [[]] * len(texts)
|
||||||
|
return [item.get("embedding", []) for item in result["data"]]
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
logging.error(f"LM Studio API request failed: {str(e)}")
|
||||||
|
return [[]] * len(texts)
|
||||||
|
except (KeyError, IndexError, ValueError, TypeError) as e:
|
||||||
|
logging.error(f"Error parsing LM Studio API response: {str(e)}")
|
||||||
|
return [[]] * len(texts)
|
||||||
|
|
||||||
def embed_query(self, query: str) -> List[float]:
|
def embed_query(self, query: str) -> List[float]:
|
||||||
return self._embedding.embed_query(query)
|
try:
|
||||||
|
payload = {
|
||||||
|
"input": query,
|
||||||
|
"model": self.model_name
|
||||||
|
}
|
||||||
|
response = requests.post(self.url, json=payload, headers=self.headers)
|
||||||
|
response.raise_for_status()
|
||||||
|
result = response.json()
|
||||||
|
if "data" not in result or not result["data"]:
|
||||||
|
logging.error(f"Invalid response format from LM Studio API: {result}")
|
||||||
|
return []
|
||||||
|
return result["data"][0].get("embedding", [])
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
logging.error(f"LM Studio API request failed: {str(e)}")
|
||||||
|
return []
|
||||||
|
except (KeyError, IndexError, ValueError, TypeError) as e:
|
||||||
|
logging.error(f"Error parsing LM Studio API response: {str(e)}")
|
||||||
|
return []
|
||||||
|
|
||||||
class GeminiEmbeddingAdapter(BaseEmbeddingAdapter):
|
class GeminiEmbeddingAdapter(BaseEmbeddingAdapter):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -152,6 +152,9 @@ knowledge_filter_prompt = """\
|
|||||||
[情节燃料]→可用于时间压力类悬念
|
[情节燃料]→可用于时间压力类悬念
|
||||||
❗ 地下氧气系统剩余23%储量(可制造生存危机)
|
❗ 地下氧气系统剩余23%储量(可制造生存危机)
|
||||||
▲ 与第三章提到的"永久生态循环系统"存在设定冲突
|
▲ 与第三章提到的"永久生态循环系统"存在设定冲突
|
||||||
|
|
||||||
|
仅给出最终文本,不要解释任何内容。
|
||||||
|
提示词:内容
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# =============== 1. 核心种子设定(雪花第1层)===================
|
# =============== 1. 核心种子设定(雪花第1层)===================
|
||||||
|
|||||||
+72
-51
@@ -11,6 +11,8 @@ from utils import read_file, save_string_to_txt # 导入 utils 中的函数
|
|||||||
from novel_generator.common import invoke_with_cleaning # 新增导入
|
from novel_generator.common import invoke_with_cleaning # 新增导入
|
||||||
from prompt_definitions import Character_Import_Prompt
|
from prompt_definitions import Character_Import_Prompt
|
||||||
|
|
||||||
|
DEFAULT_FONT = ("Microsoft YaHei", 12)
|
||||||
|
|
||||||
class RoleLibrary:
|
class RoleLibrary:
|
||||||
def __init__(self, master, save_path, llm_adapter): # 新增llm_adapter参数
|
def __init__(self, master, save_path, llm_adapter): # 新增llm_adapter参数
|
||||||
self.master = master
|
self.master = master
|
||||||
@@ -85,13 +87,14 @@ class RoleLibrary:
|
|||||||
category_frame.pack(fill="x", padx=5, pady=5)
|
category_frame.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
# 分类选择标签
|
# 分类选择标签
|
||||||
ctk.CTkLabel(category_frame, text="分类选择").pack(side="left", padx=(0, 5))
|
ctk.CTkLabel(category_frame, text="分类选择", font=DEFAULT_FONT).pack(side="left", padx=(0, 5))
|
||||||
|
|
||||||
# 分类选择框
|
# 分类选择框
|
||||||
self.category_combobox = ctk.CTkComboBox(
|
self.category_combobox = ctk.CTkComboBox(
|
||||||
category_frame,
|
category_frame,
|
||||||
values=self._get_all_categories(),
|
values=self._get_all_categories(),
|
||||||
width=200
|
width=200,
|
||||||
|
font=DEFAULT_FONT
|
||||||
)
|
)
|
||||||
self.category_combobox.pack(side="left", padx=0)
|
self.category_combobox.pack(side="left", padx=0)
|
||||||
|
|
||||||
@@ -100,7 +103,8 @@ class RoleLibrary:
|
|||||||
category_frame,
|
category_frame,
|
||||||
text="保存分类",
|
text="保存分类",
|
||||||
width=80,
|
width=80,
|
||||||
command=self._move_to_category
|
command=self._move_to_category,
|
||||||
|
font=DEFAULT_FONT
|
||||||
)
|
)
|
||||||
self.save_category_btn.pack(side="left", padx=(0, 5))
|
self.save_category_btn.pack(side="left", padx=(0, 5))
|
||||||
|
|
||||||
@@ -110,7 +114,8 @@ class RoleLibrary:
|
|||||||
text="打开文件夹",
|
text="打开文件夹",
|
||||||
width=80,
|
width=80,
|
||||||
command=lambda: os.startfile(
|
command=lambda: os.startfile(
|
||||||
os.path.join(self.save_path, self.category_combobox.get()))
|
os.path.join(self.save_path, self.category_combobox.get())),
|
||||||
|
font=DEFAULT_FONT
|
||||||
).pack(side="left", padx=0)
|
).pack(side="left", padx=0)
|
||||||
|
|
||||||
# 角色名编辑行
|
# 角色名编辑行
|
||||||
@@ -118,14 +123,15 @@ class RoleLibrary:
|
|||||||
name_frame.pack(fill="x", padx=5, pady=5)
|
name_frame.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
# 角色名称标签
|
# 角色名称标签
|
||||||
ctk.CTkLabel(name_frame, text="角色名称").pack(side="left", padx=(0, 5))
|
ctk.CTkLabel(name_frame, text="角色名称", font=DEFAULT_FONT).pack(side="left", padx=(0, 5))
|
||||||
|
|
||||||
self.role_name_var = tk.StringVar()
|
self.role_name_var = tk.StringVar()
|
||||||
self.role_name_entry = ctk.CTkEntry(
|
self.role_name_entry = ctk.CTkEntry(
|
||||||
name_frame,
|
name_frame,
|
||||||
textvariable=self.role_name_var,
|
textvariable=self.role_name_var,
|
||||||
placeholder_text="角色名称",
|
placeholder_text="角色名称",
|
||||||
width=200
|
width=200,
|
||||||
|
font=DEFAULT_FONT
|
||||||
)
|
)
|
||||||
self.role_name_entry.pack(side="left", padx=0)
|
self.role_name_entry.pack(side="left", padx=0)
|
||||||
|
|
||||||
@@ -133,14 +139,16 @@ class RoleLibrary:
|
|||||||
name_frame,
|
name_frame,
|
||||||
text="修改",
|
text="修改",
|
||||||
width=60,
|
width=60,
|
||||||
command=self._rename_role_file
|
command=self._rename_role_file,
|
||||||
|
font=DEFAULT_FONT
|
||||||
).pack(side="left", padx=(0, 5))
|
).pack(side="left", padx=(0, 5))
|
||||||
|
|
||||||
ctk.CTkButton(
|
ctk.CTkButton(
|
||||||
name_frame,
|
name_frame,
|
||||||
text="新增",
|
text="新增",
|
||||||
width=60,
|
width=60,
|
||||||
command=lambda: self._create_new_role("全部")
|
command=lambda: self._create_new_role("全部"),
|
||||||
|
font=DEFAULT_FONT
|
||||||
).pack(side="left", padx=0)
|
).pack(side="left", padx=0)
|
||||||
|
|
||||||
# 属性编辑区(基础框架)
|
# 属性编辑区(基础框架)
|
||||||
@@ -153,11 +161,11 @@ class RoleLibrary:
|
|||||||
button_frame.pack(fill="x", padx=5, pady=5)
|
button_frame.pack(fill="x", padx=5, pady=5)
|
||||||
|
|
||||||
ctk.CTkButton(button_frame, text="导入角色",
|
ctk.CTkButton(button_frame, text="导入角色",
|
||||||
command=self.import_roles).pack(side="left", padx=5)
|
command=self.import_roles, font=DEFAULT_FONT).pack(side="left", padx=5)
|
||||||
ctk.CTkButton(button_frame, text="删除",
|
ctk.CTkButton(button_frame, text="删除",
|
||||||
command=self.delete_current_role).pack(side="left", padx=5)
|
command=self.delete_current_role, font=DEFAULT_FONT).pack(side="left", padx=5)
|
||||||
ctk.CTkButton(button_frame, text="保存",
|
ctk.CTkButton(button_frame, text="保存",
|
||||||
command=self.save_current_role).pack(side="left", padx=5)
|
command=self.save_current_role, font=DEFAULT_FONT).pack(side="left", padx=5)
|
||||||
|
|
||||||
def _get_all_categories(self):
|
def _get_all_categories(self):
|
||||||
"""获取所有有效分类(包括动态更新)"""
|
"""获取所有有效分类(包括动态更新)"""
|
||||||
@@ -289,7 +297,7 @@ class RoleLibrary:
|
|||||||
right_panel.grid_columnconfigure(0, weight=1)
|
right_panel.grid_columnconfigure(0, weight=1)
|
||||||
|
|
||||||
# 创建初始可编辑文本框
|
# 创建初始可编辑文本框
|
||||||
text_box = ctk.CTkTextbox(right_panel, wrap="word")
|
text_box = ctk.CTkTextbox(right_panel, wrap="word", font=DEFAULT_FONT)
|
||||||
text_box.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
|
text_box.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
|
||||||
text_box.configure(state="normal") # 保持可编辑状态
|
text_box.configure(state="normal") # 保持可编辑状态
|
||||||
|
|
||||||
@@ -305,7 +313,8 @@ class RoleLibrary:
|
|||||||
btn_frame,
|
btn_frame,
|
||||||
text="导入临时角色库",
|
text="导入临时角色库",
|
||||||
width=120,
|
width=120,
|
||||||
command=lambda: self.confirm_import(import_window)
|
command=lambda: self.confirm_import(import_window),
|
||||||
|
font=DEFAULT_FONT
|
||||||
).pack(side="left", padx=10)
|
).pack(side="left", padx=10)
|
||||||
|
|
||||||
# 分析文件按钮
|
# 分析文件按钮
|
||||||
@@ -313,7 +322,8 @@ class RoleLibrary:
|
|||||||
btn_frame,
|
btn_frame,
|
||||||
text="分析文件",
|
text="分析文件",
|
||||||
width=100,
|
width=100,
|
||||||
command=lambda: self.analyze_character_state(right_panel, left_panel)
|
command=lambda: self.analyze_character_state(right_panel, left_panel),
|
||||||
|
font=DEFAULT_FONT
|
||||||
).pack(side="left", padx=10)
|
).pack(side="left", padx=10)
|
||||||
|
|
||||||
# 加载character_state.txt按钮
|
# 加载character_state.txt按钮
|
||||||
@@ -321,7 +331,8 @@ class RoleLibrary:
|
|||||||
btn_frame,
|
btn_frame,
|
||||||
text="加载character_state.txt",
|
text="加载character_state.txt",
|
||||||
width=160,
|
width=160,
|
||||||
command=lambda: self.load_default_character_state(right_panel)
|
command=lambda: self.load_default_character_state(right_panel),
|
||||||
|
font=DEFAULT_FONT
|
||||||
).pack(side="right", padx=10)
|
).pack(side="right", padx=10)
|
||||||
|
|
||||||
# 从文件导入按钮
|
# 从文件导入按钮
|
||||||
@@ -329,7 +340,8 @@ class RoleLibrary:
|
|||||||
btn_frame,
|
btn_frame,
|
||||||
text="从文件导入",
|
text="从文件导入",
|
||||||
width=100,
|
width=100,
|
||||||
command=lambda: self.import_from_file(right_panel)
|
command=lambda: self.import_from_file(right_panel),
|
||||||
|
font=DEFAULT_FONT
|
||||||
).pack(side="right", padx=10)
|
).pack(side="right", padx=10)
|
||||||
|
|
||||||
# 设置内容区权重
|
# 设置内容区权重
|
||||||
@@ -407,17 +419,18 @@ class RoleLibrary:
|
|||||||
|
|
||||||
# 勾选框
|
# 勾选框
|
||||||
var = BooleanVar(value=True)
|
var = BooleanVar(value=True)
|
||||||
cb = ctk.CTkCheckBox(frame, text="", variable=var, width=20)
|
cb = ctk.CTkCheckBox(frame, text="", variable=var, width=20, font=DEFAULT_FONT)
|
||||||
cb.pack(side="left", padx=5)
|
cb.pack(side="left", padx=5)
|
||||||
|
|
||||||
# 角色名称
|
# 角色名称
|
||||||
lbl = ctk.CTkLabel(frame, text=role_name,
|
lbl = ctk.CTkLabel(frame, text=role_name,
|
||||||
font=("Microsoft YaHei", 11, "bold"))
|
font=("Microsoft YaHei", 12))
|
||||||
lbl.pack(side="left", padx=5)
|
lbl.pack(side="left", padx=5)
|
||||||
|
|
||||||
# 属性摘要
|
# 属性摘要
|
||||||
attrs = [f"{k}({len(v)})" for k,v in attributes.items()]
|
attrs = [f"{k}({len(v)})" for k,v in attributes.items()]
|
||||||
summary = ctk.CTkLabel(frame, text=" | ".join(attrs),
|
summary = ctk.CTkLabel(frame, text=" | ".join(attrs),
|
||||||
|
font=("Microsoft YaHei", 12),
|
||||||
text_color="gray")
|
text_color="gray")
|
||||||
summary.pack(side="right", padx=10)
|
summary.pack(side="right", padx=10)
|
||||||
|
|
||||||
@@ -430,9 +443,9 @@ class RoleLibrary:
|
|||||||
btn_frame = ctk.CTkFrame(scroll_frame)
|
btn_frame = ctk.CTkFrame(scroll_frame)
|
||||||
btn_frame.pack(fill="x", pady=5)
|
btn_frame.pack(fill="x", pady=5)
|
||||||
ctk.CTkButton(btn_frame, text="全选",
|
ctk.CTkButton(btn_frame, text="全选",
|
||||||
command=lambda: self._toggle_all(True)).pack(side="left")
|
command=lambda: self._toggle_all(True), font=DEFAULT_FONT).pack(side="left")
|
||||||
ctk.CTkButton(btn_frame, text="取消选择",
|
ctk.CTkButton(btn_frame, text="取消选择",
|
||||||
command=lambda: self._toggle_all(False)).pack(side="left")
|
command=lambda: self._toggle_all(False), font=DEFAULT_FONT).pack(side="left")
|
||||||
|
|
||||||
def _parse_temp_role_file(self, file_path):
|
def _parse_temp_role_file(self, file_path):
|
||||||
"""解析临时角色文件"""
|
"""解析临时角色文件"""
|
||||||
@@ -532,17 +545,18 @@ class RoleLibrary:
|
|||||||
|
|
||||||
# 勾选框
|
# 勾选框
|
||||||
var = BooleanVar(value=True)
|
var = BooleanVar(value=True)
|
||||||
cb = ctk.CTkCheckBox(frame, text="", variable=var, width=20)
|
cb = ctk.CTkCheckBox(frame, text="", variable=var, width=20, font=DEFAULT_FONT)
|
||||||
cb.pack(side="left", padx=5)
|
cb.pack(side="left", padx=5)
|
||||||
|
|
||||||
# 角色名称标签
|
# 角色名称标签
|
||||||
lbl = ctk.CTkLabel(frame, text=role['name'],
|
lbl = ctk.CTkLabel(frame, text=role['name'],
|
||||||
font=("Microsoft YaHei", 11, "bold"))
|
font=("Microsoft YaHei", 12))
|
||||||
lbl.pack(side="left", padx=5)
|
lbl.pack(side="left", padx=5)
|
||||||
|
|
||||||
# 属性摘要
|
# 属性摘要
|
||||||
attrs = [f"{k}({len(v)})" for k,v in role['attributes'].items()]
|
attrs = [f"{k}({len(v)})" for k,v in role['attributes'].items()]
|
||||||
summary = ctk.CTkLabel(frame, text=" | ".join(attrs),
|
summary = ctk.CTkLabel(frame, text=" | ".join(attrs),
|
||||||
|
font=("Microsoft YaHei", 12),
|
||||||
text_color="gray")
|
text_color="gray")
|
||||||
summary.pack(side="right", padx=10)
|
summary.pack(side="right", padx=10)
|
||||||
|
|
||||||
@@ -556,9 +570,9 @@ class RoleLibrary:
|
|||||||
btn_frame.pack(fill="x", pady=5)
|
btn_frame.pack(fill="x", pady=5)
|
||||||
|
|
||||||
ctk.CTkButton(btn_frame, text="全选",
|
ctk.CTkButton(btn_frame, text="全选",
|
||||||
command=lambda: self._toggle_all(True)).pack(side="left")
|
command=lambda: self._toggle_all(True), font=DEFAULT_FONT).pack(side="left")
|
||||||
ctk.CTkButton(btn_frame, text="反选",
|
ctk.CTkButton(btn_frame, text="反选",
|
||||||
command=lambda: self._toggle_all(False)).pack(side="left")
|
command=lambda: self._toggle_all(False), font=DEFAULT_FONT).pack(side="left")
|
||||||
|
|
||||||
def _toggle_all(self, select):
|
def _toggle_all(self, select):
|
||||||
"""全选/反选操作"""
|
"""全选/反选操作"""
|
||||||
@@ -636,7 +650,7 @@ class RoleLibrary:
|
|||||||
break
|
break
|
||||||
|
|
||||||
if not text_box:
|
if not text_box:
|
||||||
text_box = ctk.CTkTextbox(right_panel, wrap="word")
|
text_box = ctk.CTkTextbox(right_panel, wrap="word", font=DEFAULT_FONT)
|
||||||
text_box.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
|
text_box.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
|
||||||
|
|
||||||
text_box.configure(state="normal")
|
text_box.configure(state="normal")
|
||||||
@@ -669,8 +683,8 @@ class RoleLibrary:
|
|||||||
error_window.grab_set()
|
error_window.grab_set()
|
||||||
|
|
||||||
# 窗口内容
|
# 窗口内容
|
||||||
ctk.CTkLabel(error_window, text="请至少选择一个角色").pack(padx=20, pady=10)
|
ctk.CTkLabel(error_window, text="请至少选择一个角色", font=DEFAULT_FONT).pack(padx=20, pady=10)
|
||||||
ctk.CTkButton(error_window, text="确定", command=error_window.destroy).pack(pady=10)
|
ctk.CTkButton(error_window, text="确定", command=error_window.destroy, font=DEFAULT_FONT).pack(pady=10)
|
||||||
|
|
||||||
# 窗口居中
|
# 窗口居中
|
||||||
error_window.update_idletasks()
|
error_window.update_idletasks()
|
||||||
@@ -990,11 +1004,12 @@ class RoleLibrary:
|
|||||||
# 操作提示
|
# 操作提示
|
||||||
ctk.CTkLabel(category_frame,
|
ctk.CTkLabel(category_frame,
|
||||||
text="右键分类名即可重命名",
|
text="右键分类名即可重命名",
|
||||||
font=("Microsoft YaHei", 10),
|
font=DEFAULT_FONT,
|
||||||
text_color="gray").pack(side="top", anchor="w", padx=5)
|
text_color="gray").pack(side="top", anchor="w", padx=5)
|
||||||
|
|
||||||
# 固定按钮
|
# 固定按钮
|
||||||
ctk.CTkButton(category_frame, text="全部", width=50,
|
ctk.CTkButton(category_frame, text="全部", width=50,
|
||||||
|
font=("Microsoft YaHei", 12),
|
||||||
command=lambda: self.show_category("全部")).pack(side="left", padx=2)
|
command=lambda: self.show_category("全部")).pack(side="left", padx=2)
|
||||||
|
|
||||||
# 滚动分类区
|
# 滚动分类区
|
||||||
@@ -1004,9 +1019,9 @@ class RoleLibrary:
|
|||||||
|
|
||||||
# 操作按钮
|
# 操作按钮
|
||||||
ctk.CTkButton(category_frame, text="新增", width=50,
|
ctk.CTkButton(category_frame, text="新增", width=50,
|
||||||
command=self.add_category).pack(side="right", padx=2)
|
command=self.add_category, font=DEFAULT_FONT).pack(side="right", padx=2)
|
||||||
ctk.CTkButton(category_frame, text="删除", width=50,
|
ctk.CTkButton(category_frame, text="删除", width=50,
|
||||||
command=self.delete_category).pack(side="right", padx=2)
|
command=self.delete_category, font=DEFAULT_FONT).pack(side="right", padx=2)
|
||||||
|
|
||||||
self.load_categories()
|
self.load_categories()
|
||||||
|
|
||||||
@@ -1032,7 +1047,7 @@ class RoleLibrary:
|
|||||||
if os.path.isdir(os.path.join(self.save_path, d)) and d != "全部"]
|
if os.path.isdir(os.path.join(self.save_path, d)) and d != "全部"]
|
||||||
|
|
||||||
for category in categories:
|
for category in categories:
|
||||||
btn = ctk.CTkButton(self.scroll_frame, text=category, width=80)
|
btn = ctk.CTkButton(self.scroll_frame, text=category, width=80, font=DEFAULT_FONT)
|
||||||
btn.bind("<Button-1>", lambda e, c=category: self.show_category(c))
|
btn.bind("<Button-1>", lambda e, c=category: self.show_category(c))
|
||||||
btn.bind("<Button-3>", lambda e, c=category: self.rename_category(c))
|
btn.bind("<Button-3>", lambda e, c=category: self.rename_category(c))
|
||||||
btn.pack(side="left", padx=2)
|
btn.pack(side="left", padx=2)
|
||||||
@@ -1079,7 +1094,7 @@ class RoleLibrary:
|
|||||||
|
|
||||||
for cat in categories:
|
for cat in categories:
|
||||||
var = tk.BooleanVar()
|
var = tk.BooleanVar()
|
||||||
chk = ctk.CTkCheckBox(scroll_frame, text=cat, variable=var)
|
chk = ctk.CTkCheckBox(scroll_frame, text=cat, variable=var, font=DEFAULT_FONT)
|
||||||
chk.pack(anchor="w")
|
chk.pack(anchor="w")
|
||||||
self.selected_del.append((cat, var))
|
self.selected_del.append((cat, var))
|
||||||
|
|
||||||
@@ -1088,9 +1103,9 @@ class RoleLibrary:
|
|||||||
btn_frame.pack(fill="x", pady=5)
|
btn_frame.pack(fill="x", pady=5)
|
||||||
|
|
||||||
ctk.CTkButton(btn_frame, text="删除选中",
|
ctk.CTkButton(btn_frame, text="删除选中",
|
||||||
command=lambda: self.confirm_delete(del_window)).pack(side="left", padx=5)
|
command=lambda: self.confirm_delete(del_window), font=DEFAULT_FONT).pack(side="left", padx=5)
|
||||||
ctk.CTkButton(btn_frame, text="取消",
|
ctk.CTkButton(btn_frame, text="取消",
|
||||||
command=del_window.destroy).pack(side="right", padx=5)
|
command=del_window.destroy, font=DEFAULT_FONT).pack(side="right", padx=5)
|
||||||
|
|
||||||
self.category_combobox.configure(values=self._get_all_categories())
|
self.category_combobox.configure(values=self._get_all_categories())
|
||||||
self.category_combobox.set("全部")
|
self.category_combobox.set("全部")
|
||||||
@@ -1119,7 +1134,7 @@ class RoleLibrary:
|
|||||||
y = self.window.winfo_y() + (self.window.winfo_height() - c_height) // 2
|
y = self.window.winfo_y() + (self.window.winfo_height() - c_height) // 2
|
||||||
choice_window.geometry(f"+{x}+{y}")
|
choice_window.geometry(f"+{x}+{y}")
|
||||||
|
|
||||||
ctk.CTkLabel(choice_window, text="请选择删除方式:").pack(pady=10)
|
ctk.CTkLabel(choice_window, text="请选择删除方式:", font=DEFAULT_FONT).pack(pady=10)
|
||||||
btn_frame = ctk.CTkFrame(choice_window)
|
btn_frame = ctk.CTkFrame(choice_window)
|
||||||
btn_frame.pack(pady=10)
|
btn_frame.pack(pady=10)
|
||||||
|
|
||||||
@@ -1145,9 +1160,9 @@ class RoleLibrary:
|
|||||||
choice_window.destroy()
|
choice_window.destroy()
|
||||||
|
|
||||||
ctk.CTkButton(btn_frame, text="全部删除",
|
ctk.CTkButton(btn_frame, text="全部删除",
|
||||||
command=lambda: perform_delete("all")).pack(side="left", padx=5)
|
command=lambda: perform_delete("all"), font=DEFAULT_FONT).pack(side="left", padx=5)
|
||||||
ctk.CTkButton(btn_frame, text="移动角色",
|
ctk.CTkButton(btn_frame, text="移动角色",
|
||||||
command=lambda: perform_delete("move")).pack(side="left", padx=5)
|
command=lambda: perform_delete("move"), font=DEFAULT_FONT).pack(side="left", padx=5)
|
||||||
|
|
||||||
def count_roles(self, categories):
|
def count_roles(self, categories):
|
||||||
"""统计角色数量"""
|
"""统计角色数量"""
|
||||||
@@ -1185,7 +1200,8 @@ class RoleLibrary:
|
|||||||
btn = ctk.CTkButton(
|
btn = ctk.CTkButton(
|
||||||
self.role_list_frame,
|
self.role_list_frame,
|
||||||
text=role_name,
|
text=role_name,
|
||||||
command=lambda r=role_name: self.show_role(r)
|
command=lambda r=role_name: self.show_role(r),
|
||||||
|
font=DEFAULT_FONT
|
||||||
)
|
)
|
||||||
btn.pack(fill="x", pady=2)
|
btn.pack(fill="x", pady=2)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
@@ -1200,7 +1216,8 @@ class RoleLibrary:
|
|||||||
btn = ctk.CTkButton(
|
btn = ctk.CTkButton(
|
||||||
self.role_list_frame,
|
self.role_list_frame,
|
||||||
text=role_name,
|
text=role_name,
|
||||||
command=lambda r=role_name: self.show_role(r)
|
command=lambda r=role_name: self.show_role(r),
|
||||||
|
font=DEFAULT_FONT
|
||||||
)
|
)
|
||||||
btn.pack(fill="x", pady=2)
|
btn.pack(fill="x", pady=2)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
@@ -1294,9 +1311,9 @@ class RoleLibrary:
|
|||||||
self._create_attribute_section(attr_name, items)
|
self._create_attribute_section(attr_name, items)
|
||||||
|
|
||||||
except FileNotFoundError as e:
|
except FileNotFoundError as e:
|
||||||
messagebox.showerror("错误", f"文件不存在:{str(e)}", parent=self.window)
|
messagebox.showerror("错误", f"文件不存在:{e}", parent=self.window)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
messagebox.showerror("错误", f"读取文件失败:{str(e)}", parent=self.window)
|
messagebox.showerror("错误", f"读取文件失败:{e}", parent=self.window)
|
||||||
|
|
||||||
def _create_attribute_section(self, attr_name, items):
|
def _create_attribute_section(self, attr_name, items):
|
||||||
"""创建单个属性的编辑区域"""
|
"""创建单个属性的编辑区域"""
|
||||||
@@ -1309,7 +1326,7 @@ class RoleLibrary:
|
|||||||
attribute_block.grid_columnconfigure(1, weight=1) # 设置第二列权重
|
attribute_block.grid_columnconfigure(1, weight=1) # 设置第二列权重
|
||||||
|
|
||||||
# 属性名称标签
|
# 属性名称标签
|
||||||
label = ctk.CTkLabel(attribute_block, text=attr_name)
|
label = ctk.CTkLabel(attribute_block, text=attr_name, font=DEFAULT_FONT)
|
||||||
label.grid(row=0, column=0, sticky="w", padx=(5, 10), pady=2)
|
label.grid(row=0, column=0, sticky="w", padx=(5, 10), pady=2)
|
||||||
|
|
||||||
# 第一个条目和“增加”按钮的容器
|
# 第一个条目和“增加”按钮的容器
|
||||||
@@ -1318,7 +1335,7 @@ class RoleLibrary:
|
|||||||
first_item_frame.grid_columnconfigure(0, weight=1)
|
first_item_frame.grid_columnconfigure(0, weight=1)
|
||||||
|
|
||||||
# 第一个条目输入框
|
# 第一个条目输入框
|
||||||
first_entry = ctk.CTkEntry(first_item_frame)
|
first_entry = ctk.CTkEntry(first_item_frame, font=DEFAULT_FONT)
|
||||||
first_entry.grid(row=0, column=0, sticky="ew", padx=(0, 5), ipadx=5, ipady=3)
|
first_entry.grid(row=0, column=0, sticky="ew", padx=(0, 5), ipadx=5, ipady=3)
|
||||||
if items:
|
if items:
|
||||||
first_entry.insert(0, items[0]) # 填充第一个条目的内容
|
first_entry.insert(0, items[0]) # 填充第一个条目的内容
|
||||||
@@ -1332,7 +1349,8 @@ class RoleLibrary:
|
|||||||
add_button_frame,
|
add_button_frame,
|
||||||
text="+",
|
text="+",
|
||||||
width=30,
|
width=30,
|
||||||
command=lambda: self._add_item(attr_name)
|
command=lambda: self._add_item(attr_name),
|
||||||
|
font=DEFAULT_FONT
|
||||||
)
|
)
|
||||||
add_button.grid(row=0, column=0)
|
add_button.grid(row=0, column=0)
|
||||||
|
|
||||||
@@ -1365,7 +1383,7 @@ class RoleLibrary:
|
|||||||
item_frame.grid_columnconfigure(0, weight=1)
|
item_frame.grid_columnconfigure(0, weight=1)
|
||||||
|
|
||||||
# 条目输入框
|
# 条目输入框
|
||||||
new_entry = ctk.CTkEntry(item_frame)
|
new_entry = ctk.CTkEntry(item_frame, font=DEFAULT_FONT)
|
||||||
new_entry.grid(row=0, column=0, sticky="ew", padx=(0, 5), ipadx=5, ipady=3)
|
new_entry.grid(row=0, column=0, sticky="ew", padx=(0, 5), ipadx=5, ipady=3)
|
||||||
new_entry.insert(0, initial_text) # 设置初始文本
|
new_entry.insert(0, initial_text) # 设置初始文本
|
||||||
|
|
||||||
@@ -1377,7 +1395,8 @@ class RoleLibrary:
|
|||||||
del_button_frame,
|
del_button_frame,
|
||||||
text="-",
|
text="-",
|
||||||
width=30,
|
width=30,
|
||||||
command=lambda f=item_frame: self._remove_item(f, attr_name)
|
command=lambda f=item_frame: self._remove_item(f, attr_name),
|
||||||
|
font=DEFAULT_FONT
|
||||||
)
|
)
|
||||||
del_button.grid(row=0, column=0)
|
del_button.grid(row=0, column=0)
|
||||||
|
|
||||||
@@ -1468,14 +1487,16 @@ class RoleLibrary:
|
|||||||
content_frame.pack(fill="both", expand=True, padx=10, pady=10)
|
content_frame.pack(fill="both", expand=True, padx=10, pady=10)
|
||||||
|
|
||||||
# 顶部提示
|
# 顶部提示
|
||||||
ctk.CTkLabel(content_frame, text=f"当前分类:{old_name}").pack(pady=(10, 5))
|
ctk.CTkLabel(content_frame, text=f"当前分类:{old_name}",
|
||||||
|
font=DEFAULT_FONT).pack(pady=(10, 5))
|
||||||
|
|
||||||
# 输入框
|
# 输入框
|
||||||
input_frame = ctk.CTkFrame(content_frame)
|
input_frame = ctk.CTkFrame(content_frame)
|
||||||
input_frame.pack(fill="x", pady=5)
|
input_frame.pack(fill="x", pady=5)
|
||||||
ctk.CTkLabel(input_frame, text="新名称:").pack(side="left", padx=5)
|
ctk.CTkLabel(input_frame, text="新名称:",
|
||||||
|
font=DEFAULT_FONT).pack(side="left", padx=5)
|
||||||
name_var = tk.StringVar()
|
name_var = tk.StringVar()
|
||||||
name_entry = ctk.CTkEntry(input_frame, textvariable=name_var, width=150)
|
name_entry = ctk.CTkEntry(input_frame, textvariable=name_var, width=150, font=DEFAULT_FONT)
|
||||||
name_entry.pack(side="left", padx=5)
|
name_entry.pack(side="left", padx=5)
|
||||||
|
|
||||||
# 按钮区
|
# 按钮区
|
||||||
@@ -1508,9 +1529,9 @@ class RoleLibrary:
|
|||||||
messagebox.showerror("错误", f"重命名失败:{str(e)}", parent=self.window)
|
messagebox.showerror("错误", f"重命名失败:{str(e)}", parent=self.window)
|
||||||
|
|
||||||
ctk.CTkButton(button_frame, text="确认",
|
ctk.CTkButton(button_frame, text="确认",
|
||||||
command=confirm_rename).pack(side="left", padx=10)
|
command=confirm_rename, font=DEFAULT_FONT).pack(side="left", padx=10)
|
||||||
ctk.CTkButton(button_frame, text="取消",
|
ctk.CTkButton(button_frame, text="取消",
|
||||||
command=dialog.destroy).pack(side="right", padx=10)
|
command=dialog.destroy, font=DEFAULT_FONT).pack(side="right", padx=10)
|
||||||
|
|
||||||
# 窗口居中
|
# 窗口居中
|
||||||
dialog.update_idletasks()
|
dialog.update_idletasks()
|
||||||
|
|||||||
Reference in New Issue
Block a user