初始化tkinter UI

This commit is contained in:
2025-10-31 23:35:34 +08:00
parent bd7a6e3048
commit 4325bbafb7
5 changed files with 479 additions and 41 deletions
+475
View File
@@ -0,0 +1,475 @@
import random
import tkinter as tk
from tkinter import ttk
from typing import List
from datetime import datetime
from core.strategy_db import TradeTarget
class TradeTargetUI:
def __init__(self):
self.root = tk.Tk()
self.root.title("交易标的监控系统")
self.root.geometry("1200x700")
# 创建界面
self.create_ui()
def create_ui(self):
"""创建UI界面"""
# 主框架
main_frame = ttk.Frame(self.root)
main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
# 表格区域
self.create_tables_area(main_frame)
# 按钮区域
self.create_buttons_area(main_frame)
def create_tables_area(self, parent):
"""创建表格区域"""
tables_frame = ttk.Frame(parent)
tables_frame.pack(fill=tk.BOTH, expand=True)
# 左侧表格框架
left_frame = ttk.LabelFrame(tables_frame, text="交易标的详情", padding=10)
left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 5))
# 右侧表格框架
right_frame = ttk.LabelFrame(tables_frame, text="操作日志", padding=10)
right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(5, 0))
# 创建左侧交易标的表格
self.create_trade_target_table(left_frame)
# 创建右侧操作日志表格
self.create_log_table(right_frame)
def create_trade_target_table(self, parent):
"""创建交易标的表格"""
# 创建Treeview
columns = (
"id", "stock_code", "stock_name", "current_position", "grid_index",
"last_trade_price", "current_buy_price", "current_sell_price",
"current_buy_order_no", "current_sell_order_no",
"status", "enabled"
)
self.trade_table = ttk.Treeview(parent, columns=columns, show='headings', height=12)
# 定义列标题和宽度
column_configs = {
"id": ("ID", 80),
"stock_code": ("股票代码", 80),
"stock_name": ("股票名称", 100),
"current_position": ("持仓数量", 90),
"grid_index": ("网格索引", 80),
"last_trade_price": ("最新成交价", 90),
"current_buy_price": ("当前买入价", 90),
"current_sell_price": ("当前卖出价", 90),
"current_buy_order_no": ("买入订单号", 120),
"current_sell_order_no": ("卖出订单号", 120),
"status": ("状态", 70),
"enabled": ("启用状态", 80)
}
for col in columns:
title, width = column_configs[col]
self.trade_table.heading(col, text=title)
self.trade_table.column(col, width=width, anchor=tk.CENTER)
# 填充数据
self.populate_trade_table()
# 滚动条
scrollbar = ttk.Scrollbar(parent, orient=tk.VERTICAL, command=self.trade_table.yview)
self.trade_table.configure(yscrollcommand=scrollbar.set)
# 布局
self.trade_table.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
# 绑定双击事件
self.trade_table.bind("<Double-1>", self.on_table_double_click)
def populate_trade_table(self):
"""填充交易标的表格数据"""
# 颜色标签
self.trade_table.tag_configure('enabled', background='#f0f8ff') # 淡蓝色
self.trade_table.tag_configure('disabled', background='#f5f5f5') # 淡灰色
def create_log_table(self, parent):
"""创建操作日志表格"""
columns = ("timestamp", "level", "message")
self.log_table = ttk.Treeview(parent, columns=columns, show='headings', height=12)
log_column_configs = {
"timestamp": ("时间", 120),
"level": ("级别", 60),
"message": ("消息", 200)
}
for col in columns:
title, width = log_column_configs[col]
self.log_table.heading(col, text=title)
self.log_table.column(col, width=width, anchor=tk.W)
# 填充示例日志
sample_logs = [
("2024-01-15 10:30:15", "INFO", "系统启动成功"),
("2024-01-15 10:31:22", "DEBUG", "加载交易标的: 5个"),
("2024-01-15 10:32:45", "INFO", "000001 - 网格交易线程启动"),
("2024-01-15 10:33:10", "WARNING", "601318 - 未启用交易"),
("2024-01-15 10:34:30", "ERROR", "300750 - 订单提交失败"),
("2024-01-15 10:35:18", "INFO", "600036 - 买入订单创建成功"),
("2024-01-15 10:36:05", "INFO", "数据刷新完成")
]
for log in sample_logs:
self.log_table.insert('', tk.END, values=log)
# 滚动条
scrollbar = ttk.Scrollbar(parent, orient=tk.VERTICAL, command=self.log_table.yview)
self.log_table.configure(yscrollcommand=scrollbar.set)
self.log_table.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
def create_buttons_area(self, parent):
"""创建按钮区域"""
buttons_frame = ttk.LabelFrame(parent, text="操作面板", padding=15)
buttons_frame.pack(fill=tk.X, pady=(10, 0))
# 创建五个功能按钮
self.create_five_buttons(buttons_frame)
def create_five_buttons(self, parent):
"""创建五个功能按钮"""
button_configs = [
("刷新数据", self.refresh_data, "🔄"),
("启用交易", self.enable_trading, ""),
("禁用交易", self.disable_trading, ""),
("修改参数", self.modify_parameters, "⚙️"),
("系统设置", self.system_settings, "🔧")
]
for text, command, icon in button_configs:
btn = ttk.Button(
parent,
text=f"{icon} {text}",
command=command,
width=15
)
btn.pack(side=tk.LEFT, padx=8)
def refresh_data(self):
"""刷新数据功能"""
# 模拟数据更新
for target in self.trade_targets:
if target.enabled:
# 随机更新价格和仓位
target.last_trade_price += round((random.random() - 0.5) * 0.5, 2)
target.current_position += random.randint(-50, 50)
# 重新填充表格
for item in self.trade_table.get_children():
self.trade_table.delete(item)
for target in self.trade_targets:
values = [
target.id,
target.stock_code,
target.stock_name,
target.current_position,
target.grid_index,
target.last_trade_price,
target.current_buy_price,
target.current_buy_order_no,
target.current_sell_price,
target.current_sell_order_no,
self.get_status_text(target.status),
"" if target.enabled else ""
]
tags = ('enabled',) if target.enabled else ('disabled',)
self.trade_table.insert('', tk.END, values=values, tags=tags)
# 添加日志
self.add_log("INFO", "数据刷新完成")
def enable_trading(self):
"""启用交易功能"""
selected = self.trade_table.selection()
if selected:
item = selected[0]
values = self.trade_table.item(item)['values']
# 在实际应用中,这里会调用实际的启用逻辑
self.add_log("INFO", f"启用交易标的: {values[0]}")
def disable_trading(self):
"""禁用交易功能"""
selected = self.trade_table.selection()
if selected:
item = selected[0]
values = self.trade_table.item(item)['values']
self.add_log("INFO", f"禁用交易标的: {values[0]}")
def modify_parameters(self):
"""修改参数功能"""
selected = self.trade_table.selection()
if selected:
item = selected[0]
values = self.trade_table.item(item)['values']
# 弹出修改对话框
self.show_parameter_dialog()
def system_settings(self):
"""系统设置功能"""
# 弹出系统设置对话框
settings_window = tk.Toplevel(self.root)
settings_window.title("系统设置")
settings_window.geometry("400x300")
ttk.Label(settings_window, text="网格交易系统设置", font=('Arial', 12, 'bold')).pack(pady=20)
# 添加一些设置选项
options = [
("自动刷新间隔", "5秒"),
("价格变动阈值", "0.1%"),
("最大持仓数量", "10000"),
("最小交易数量", "100")
]
for label, value in options:
frame = ttk.Frame(settings_window)
frame.pack(fill=tk.X, padx=20, pady=10)
ttk.Label(frame, text=label, width=20).pack(side=tk.LEFT)
ttk.Label(frame, text=value).pack(side=tk.RIGHT)
def get_status_text(self, status):
"""获取状态文本"""
status_map = {
0: "新标的",
1: "交易中"
}
return status_map.get(status, "未知")
def on_table_double_click(self, event):
"""表格双击事件"""
selected = self.trade_table.selection()
if selected:
item = selected[0]
values = self.trade_table.item(item)['values']
self.add_log("DEBUG", f"双击查看详情: {values[0]} - {values[1]}")
def add_log(self, level, message):
"""添加日志记录"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
self.log_table.insert('', 0, values=(timestamp, level, message))
def run(self):
"""运行程序"""
# 初始填充数据
for target in self.trade_targets:
values = [
target.stock_code,
target.stock_name,
target.current_position,
target.grid_index,
target.last_trade_price,
target.current_buy_price,
target.current_buy_order_no,
target.current_sell_price,
target.current_sell_order_no,
self.get_status_text(target.status),
"" if target.enabled else ""
]
tags = ('enabled',) if target.enabled else ('disabled',)
self.trade_table.insert('', tk.END, values=values, tags=tags)
self.root.mainloop()
# 更专业的版本,集成实际的TradeTarget对象
class ProfessionalTradeUI(TradeTargetUI):
def __init__(self, trade_targets: List[TradeTarget] = None):
if trade_targets is not None:
self.trade_targets = trade_targets
else:
self.trade_targets = self.create_advanced_sample_data()
super().__init__()
def create_trade_target_table(self, parent):
"""专业版的交易标的表格"""
columns = ("ID",
"股票代码", "股票名称", "持仓数量", "网格索引",
"最新成交价", "当前买入价", "当前买入订单号", "当前卖出价", "当前卖出订单号",
"启用状态", "交易状态"
)
self.trade_table = ttk.Treeview(parent, columns=columns, show='headings', height=15)
# 专业化的列配置
column_configs = {
"ID": (50, tk.CENTER),
"股票代码": (90, tk.CENTER),
"股票名称": (100, tk.CENTER),
"持仓数量": (90, tk.CENTER),
"网格索引": (80, tk.CENTER),
"最新成交价": (100, tk.CENTER),
"当前买入价": (100, tk.CENTER),
"当前买入订单号": (100, tk.CENTER),
"当前卖出订单号": (100, tk.CENTER),
"当前卖出价": (100, tk.CENTER),
"启用状态": (80, tk.CENTER),
"交易状态": (80, tk.CENTER),
"买入订单号": (120, tk.CENTER),
"卖出订单号": (120, tk.CENTER)
}
for col in columns:
width, anchor = column_configs[col]
self.trade_table.heading(col, text=col)
self.trade_table.column(col, width=width, anchor=anchor)
# 带颜色的标签
self.trade_table.tag_configure('trading', background='#e8f5e8') # 交易中的绿色背景
self.trade_table.tag_configure('paused', background='#fff3cd') # 暂停的黄色背景
self.trade_table.tag_configure('inactive', background='#f8d7da') # 禁用的红色背景
# 填充数据
for temp in self.trade_targets:
target:TradeTarget = temp
values = [
target.id,
target.stock_code,
target.stock_name,
target.current_position,
target.grid_index,
f"{target.last_trade_price:.2f}",
f"{target.current_buy_price:.2f}",
target.current_buy_order_no,
f"{target.current_sell_price:.2f}",
target.current_sell_order_no,
"已启用" if target.enabled else "未启用",
"交易中" if target.status == 1 else "新标的"
]
# 根据状态设置标签
if target.enabled and target.status == 1:
tags = ('trading',)
elif target.enabled and target.status == 0:
tags = ('paused',)
else:
tags = ('inactive',)
self.trade_table.insert('', tk.END, values=values, tags=tags)
# 滚动条
scrollbar = ttk.Scrollbar(parent, orient=tk.VERTICAL, command=self.trade_table.yview)
self.trade_table.configure(yscrollcommand=scrollbar.set)
self.trade_table.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
def refresh_data(self):
"""专业版的刷新数据功能"""
for target in self.trade_targets:
if target.enabled:
# 模拟实时的价格变动
price_change = (random.random() - 0.5) * 0.1
target.last_trade_price = round(target.last_trade_price + price_change, 2)
# 更新表格
for item in self.trade_table.get_children():
self.trade_table.delete(item)
for target in self.trade_targets:
values = [
target.id,
target.stock_code,
target.stock_name,
target.current_position,
target.grid_index,
f"{target.last_trade_price:.2f}",
f"{target.current_buy_price:.2f}",
f"{target.current_sell_price:.2f}",
"已启用" if target.enabled else "未启用",
"交易中" if target.status == 1 else "新标的"
]
# 设置标签
if target.enabled and target.status == 1:
tags = ('trading',)
elif target.enabled and target.status == 0:
tags = ('paused',)
else:
tags = ('inactive',)
self.trade_table.insert('', tk.END, values=values, tags=tags)
self.add_log("INFO", "专业版数据刷新完成 - 包含实时价格模拟")
def show_parameter_dialog(self):
"""显示参数修改对话框"""
dialog = tk.Toplevel(self.root)
dialog.title("交易参数设置")
dialog.geometry("500x400")
# 创建配置表单
ttk.Label(dialog, text="交易标的参数配置", font=('Arial', 12, 'bold')).pack(pady=20)
# 创建标签和输入框
form_frame = ttk.Frame(dialog)
form_frame.pack(fill=tk.BOTH, expand=True, padx=20)
# 这里可以添加具体的参数配置表单
ttk.Label(form_frame, text="双击表格项可查看详情", font=('Arial', 10)).pack(pady=10)
def system_settings(self):
"""专业版的系统设置"""
settings_window = tk.Toplevel(self.root)
settings_window.title("网格交易系统配置")
settings_window.geometry("600x400")
# 创建选项卡
notebook = ttk.Notebook(settings_window)
notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
# 基础设置
basic_frame = ttk.Frame(notebook)
notebook.add(basic_frame, text="基础设置")
# 高级设置
advanced_frame = ttk.Frame(notebook)
notebook.add(advanced_frame, text="高级设置")
# 添加具体的配置选项
settings = [
("网格宽度", "0.5%"),
("网格数量", "10层"),
("交易间隔", "30秒"),
("单笔数量", "100股")
]
for i, (label, default) in enumerate(settings):
frame = ttk.Frame(basic_frame)
frame.pack(fill=tk.X, padx=20, pady=10)
ttk.Label(frame, text=label, width=15).pack(side=tk.LEFT)
entry = ttk.Entry(frame, width=20)
entry.insert(0, default)
entry.pack(side=tk.RIGHT)
# 使用示例
if __name__ == "__main__":
print("交易标的监控系统启动...")
print("功能说明:")
print(" - 左侧表格显示所有交易标的详细信息")
print(" - 右侧表格显示操作日志")
print(" - 底部五个功能按钮提供操作")
# 创建并运行界面
app = ProfessionalTradeUI()
app.run()