初步增加 gui
This commit is contained in:
+212
@@ -0,0 +1,212 @@
|
||||
"""自定义GUI组件"""
|
||||
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class AccountTable(ttk.Treeview):
|
||||
"""账号列表表格"""
|
||||
|
||||
COLUMNS = ('index', 'username', 'email', 'status', 'cookie')
|
||||
|
||||
def __init__(self, parent, **kwargs):
|
||||
super().__init__(
|
||||
parent,
|
||||
columns=self.COLUMNS,
|
||||
show='headings',
|
||||
selectmode='extended',
|
||||
**kwargs
|
||||
)
|
||||
|
||||
# 设置列标题
|
||||
self.heading('index', text='序号')
|
||||
self.heading('username', text='用户名')
|
||||
self.heading('email', text='邮箱')
|
||||
self.heading('status', text='状态')
|
||||
self.heading('cookie', text='Cookie')
|
||||
|
||||
# 设置列宽
|
||||
self.column('index', width=50, minwidth=50, anchor='center')
|
||||
self.column('username', width=150, minwidth=100)
|
||||
self.column('email', width=200, minwidth=150)
|
||||
self.column('status', width=80, minwidth=60, anchor='center')
|
||||
self.column('cookie', width=200, minwidth=100)
|
||||
|
||||
# 添加滚动条
|
||||
scrollbar = ttk.Scrollbar(parent, orient='vertical', command=self.yview)
|
||||
self.configure(yscrollcommand=scrollbar.set)
|
||||
scrollbar.pack(side='right', fill='y')
|
||||
|
||||
# 状态标签样式
|
||||
self.tag_configure('pending', foreground='gray')
|
||||
self.tag_configure('running', foreground='blue')
|
||||
self.tag_configure('success', foreground='green')
|
||||
self.tag_configure('failed', foreground='red')
|
||||
self.tag_configure('error', foreground='red')
|
||||
|
||||
def add_account(self, index: int, username: str, email: str):
|
||||
"""添加账号到表格"""
|
||||
self.insert('', 'end', iid=str(index), values=(
|
||||
index + 1,
|
||||
username,
|
||||
email,
|
||||
'待登录',
|
||||
'-'
|
||||
), tags=('pending',))
|
||||
|
||||
def update_status(self, index: int, status: str, cookie: str = ''):
|
||||
"""更新账号状态"""
|
||||
status_map = {
|
||||
'pending': ('待登录', 'pending'),
|
||||
'running': ('登录中...', 'running'),
|
||||
'success': ('成功', 'success'),
|
||||
'failed': ('失败', 'failed'),
|
||||
'error': ('异常', 'error'),
|
||||
}
|
||||
|
||||
text, tag = status_map.get(status, (status, 'pending'))
|
||||
|
||||
item_id = str(index)
|
||||
if self.exists(item_id):
|
||||
values = self.item(item_id, 'values')
|
||||
cookie_display = cookie[:30] + '...' if len(cookie) > 30 else cookie
|
||||
self.item(item_id, values=(
|
||||
values[0],
|
||||
values[1],
|
||||
values[2],
|
||||
text,
|
||||
cookie_display if cookie else '-'
|
||||
), tags=(tag,))
|
||||
|
||||
def clear(self):
|
||||
"""清空表格"""
|
||||
for item in self.get_children():
|
||||
self.delete(item)
|
||||
|
||||
def get_all_items(self):
|
||||
"""获取所有项目"""
|
||||
items = []
|
||||
for item_id in self.get_children():
|
||||
values = self.item(item_id, 'values')
|
||||
items.append({
|
||||
'index': values[0],
|
||||
'username': values[1],
|
||||
'email': values[2],
|
||||
'status': values[3],
|
||||
'cookie': values[4],
|
||||
})
|
||||
return items
|
||||
|
||||
|
||||
class LogPanel(tk.Text):
|
||||
"""日志输出面板"""
|
||||
|
||||
def __init__(self, parent, **kwargs):
|
||||
super().__init__(
|
||||
parent,
|
||||
wrap='word',
|
||||
state='disabled',
|
||||
font=('Consolas', 10),
|
||||
**kwargs
|
||||
)
|
||||
|
||||
# 日志级别颜色
|
||||
self.tag_configure('info', foreground='#333333')
|
||||
self.tag_configure('success', foreground='#008000')
|
||||
self.tag_configure('warning', foreground='#FF8C00')
|
||||
self.tag_configure('error', foreground='#FF0000')
|
||||
self.tag_configure('debug', foreground='#888888')
|
||||
self.tag_configure('timestamp', foreground='#666666')
|
||||
|
||||
# 添加滚动条
|
||||
scrollbar = ttk.Scrollbar(parent, orient='vertical', command=self.yview)
|
||||
self.configure(yscrollcommand=scrollbar.set)
|
||||
scrollbar.pack(side='right', fill='y')
|
||||
|
||||
def append_log(self, level: str, message: str):
|
||||
"""添加日志"""
|
||||
self.configure(state='normal')
|
||||
|
||||
# 添加时间戳
|
||||
timestamp = datetime.now().strftime('%H:%M:%S')
|
||||
self.insert('end', f'[{timestamp}] ', 'timestamp')
|
||||
|
||||
# 添加日志内容
|
||||
self.insert('end', f'{message}\n', level)
|
||||
|
||||
# 滚动到底部
|
||||
self.see('end')
|
||||
|
||||
self.configure(state='disabled')
|
||||
|
||||
def clear(self):
|
||||
"""清空日志"""
|
||||
self.configure(state='normal')
|
||||
self.delete('1.0', 'end')
|
||||
self.configure(state='disabled')
|
||||
|
||||
|
||||
class ImportDialog(tk.Toplevel):
|
||||
"""导入对话框"""
|
||||
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent)
|
||||
|
||||
self.title('从文件导入')
|
||||
self.geometry('400x150')
|
||||
self.resizable(False, False)
|
||||
self.transient(parent)
|
||||
self.grab_set()
|
||||
|
||||
# 居中显示
|
||||
self.update_idletasks()
|
||||
x = (self.winfo_screenwidth() - 400) // 2
|
||||
y = (self.winfo_screenheight() - 150) // 2
|
||||
self.geometry(f'+{x}+{y}')
|
||||
|
||||
self.filepath = None
|
||||
self.result = None
|
||||
|
||||
# 文件路径
|
||||
frame = ttk.Frame(self, padding=20)
|
||||
frame.pack(fill='both', expand=True)
|
||||
|
||||
ttk.Label(frame, text='选择账号文件(每行一个,格式:用户名|密码|邮箱|邮箱密码)').pack(anchor='w')
|
||||
|
||||
path_frame = ttk.Frame(frame)
|
||||
path_frame.pack(fill='x', pady=(10, 0))
|
||||
|
||||
self.path_var = tk.StringVar()
|
||||
ttk.Entry(path_frame, textvariable=self.path_var, state='readonly').pack(side='left', fill='x', expand=True)
|
||||
ttk.Button(path_frame, text='浏览', command=self._browse).pack(side='left', padx=(5, 0))
|
||||
|
||||
# 按钮
|
||||
btn_frame = ttk.Frame(frame)
|
||||
btn_frame.pack(fill='x', pady=(20, 0))
|
||||
|
||||
ttk.Button(btn_frame, text='确定', command=self._confirm).pack(side='right', padx=(5, 0))
|
||||
ttk.Button(btn_frame, text='取消', command=self._cancel).pack(side='right')
|
||||
|
||||
def _browse(self):
|
||||
"""浏览文件"""
|
||||
from tkinter import filedialog
|
||||
filepath = filedialog.askopenfilename(
|
||||
title='选择账号文件',
|
||||
filetypes=[('文本文件', '*.txt'), ('所有文件', '*.*')]
|
||||
)
|
||||
if filepath:
|
||||
self.path_var.set(filepath)
|
||||
self.filepath = filepath
|
||||
|
||||
def _confirm(self):
|
||||
"""确认"""
|
||||
if not self.filepath:
|
||||
tk.messagebox.showwarning('提示', '请选择文件')
|
||||
return
|
||||
self.result = self.filepath
|
||||
self.destroy()
|
||||
|
||||
def _cancel(self):
|
||||
"""取消"""
|
||||
self.destroy()
|
||||
Reference in New Issue
Block a user