用Tkinter打造自己的Python IDE开发工具(6)Python多文件共享变量与智能插件设计 在Python中实现多个文件共享变量,即又可以获取变量值,也可以修改变量的值。有两种方式。 一是作用域共享变量,一是类属性共享变量。我们本文主要介绍作用域共享变量,另外一个模式我们在量化策略编写时再详细介绍。 作用域共享变量在我编写的书籍<零基础搭建量化投资系统――以Python为工具>,专门介绍了多文件变量共享的方法。 本文我在详细介绍作用域共享变量,采用这个方式实现《小白量化中文Python研学实控系统》的插件设计。既然是插件,显示的画面必然要吸附到主程序界面上,因此插件文件,要获取主程序的一些变量信息,例如要获取 tabControl变量,并在上面插入新的画面。 下面详细介绍实现方法,首先设计一个文件HP_global.py,其部分内容如下。
#文件名:HP_global.py
#运行系统环境设置
#G_os=1 windows,=2 linux, =3 mac oS
global os #操作系统
global pyver #Python版本
#软件名称设置
global name #软件名称
global title #软件标题
global developer #软件开发者
global ver #软件版本号
#软件数据目录
global datapath #数据目录
global prgpath #软件目录
#软件平台设置信息
global winW #默认主窗口宽度
global winH #默认主窗口高度
global root #窗口根句柄
global ico #软件图标
##屏幕信息
global screenwidth
global screenheight
#窗口信息
global windowwidth #获取窗口宽度(单位:像素)
global windowheight #获取窗口高度(单位:像素)
#用户信息
global user #用户名
global login #用户登录标记
#通通框架控件名称
global mainform #主窗口
global ucode #代码编辑器
global tabControl #主窗口tabControl
global ttmsg ##信息输出窗
global mymsg ##信息输入窗
global status #主窗口状态栏
global toolsbar #工具栏(横向)
global toolsbar2 #工具栏(纵向)
global mainmenu #主菜单
global tab1
global tab2
global tab3
global tab4
global tab5
global tab6
global tab7
global tab8
global tab9
global tab10
global tab11
global tab12
global tab13
global tab14
global tab15
global tab16
global tab17
global tab18
global tab19
global tab20
上面把这些变量都定义为全局变量。用户文件要获取上述变量值,需要导入这个模块。
import HP_global as g #建立全局数据域g
用户文件需要获取那些变量信息,需要对这些变量进行初始化,下面再做一个初始化文件HP_set.py,这个文件只在主程序中运行一次,如果再运行就会使共享变量初始化。用户其他文件获取这些共享变量的值。HP_set.py文件部分内容如下。
#文件名:HP_set.py
import HP_global as g
##数据主目录
g.datapath='\\xbdata'
g.prgpath='\\xb'
#软件名称
g.root=None
g.name='证券分析研究平台'
g.title='小白证券分析研究平台(1.00版) 设计:荷蒲 QQ:2775205'
g.ico='tt.ico'
g.winW=1200
g.winH=800
g.ver=1.01
g.user='18578755056'
g.login=False
g.os=1
#小白量化框架控件
g.mainform=None
g.mainmenu=None
g.tabControl=None
g.status=None
global ucode #代码编辑器
g.tab1=None #工作台
g.tab2=None #行情报价
g.tab3=None #日线图
g.tab4=None #编写代码
g.tab5=None #策略回测
g.tab6=None #分时图
g.tab7=None #F10
g.tab8=None #板块
g.tab9=None #选股
g.tab10=None
g.tab11=None
g.tab12=None
g.tab13=None
g.tab14=None
g.tab15=None
g.tab16=None
g.tab17=None
g.tab18=None
g.tab19=None
g.tab20=None
#小白量化框架控件输出信息
g.ttmsg=None
g.mymsg=None
上面只能在主程序中运行一次,不能在其它文件或用户文件中使用,否则框架程序会出现错误。 我们下面给出《小白量化中文Python研学实控系统》的main.py的全部源代码。
# -*- coding: utf-8 -*-
import tkinter as tk #导入Tkinter
import tkinter.ttk as ttk #导入Tkinter.ttk
import pickle
import HP_global as g #建立全局数据域g
import HP_set #全局数据域g中变量初始化
import HP_tka as htk #导入高级htk
import HP_ide as ide
from tkinter.messagebox import *
from tkinter.filedialog import *
import PIL
from HP_formula import * #导入小白公式模块
"""
#功能:小白量化中文Python研学实控系统 Vre 3.00
#版本:Ver3.00
#设计人:独狼荷蒲
#电话:18578755056
#QQ:2775205/2886002
#小白量化中文PythonTkinter群:983815766
#百度:荷蒲指标,小白量化
#开始设计日期: 2022-01-30
#最后修改日期:2022年1月30日
#主程序:main.py
"""
mytitle='小白量化中文Python研学实控系统 Vre 3.00'
#建立主窗口
root=htk.MainWindow(title=mytitle,x=100,y=200,w=1200, h=700)
root.iconbitmap('ico/cp64.ico') #设置应用程序图标
root.SetCenter() #移动到屏幕中央
##获取窗口信息
screenwidth = root.winfo_screenwidth() #获取屏幕宽度(单位:像素)
screenheight = root.winfo_screenheight() #获取屏幕高度(单位:像素)
winw= root.winfo_width() #获取窗口宽度(单位:像素)
winh = root.winfo_height() #获取窗口高度(单位:像素)
#建立窗口菜单
menus = [['文件',['执行程序','-','新建','打开','运行','-','保存','另存为']],\
['编辑',['撤销','重做','-','剪切','复制','粘贴','清除','-','全选']],\
['显示',['绘图','表格']],\
['程序',['运行','转中文','转英文']],\
['项目',['项目目录','系统设置','恢复环境变量']],\
['数据',['连接行情服务器','断开行情服务器','下载股票代码表','下载财务数据',\
'下载板块数据']],\
['帮助',['关于软件','项目缩略图','退出']]]
mainmenu=htk.windowMenu(root,menus) #窗口菜单
tabControl = htk.ClosableNotebook(root) #创建Notebook
tab1 = tk.Frame(tabControl,bg='#1E488F') #增加新选项卡tab1
tabControl.add(tab1, text='研学中心') #把新选项卡增加到Notebook
tabControl.pack(expand=1, fill="both") #使用pack方法显示
tabControl.select(tab1) #选择tab1
#分割窗口为左右两部分
#建立可分割区域paned
paned= tk.PanedWindow(tab1,orient=tk.HORIZONTAL,showhandle=True, \
sashrelief=tk.SUNKEN,sashwidth=1) #默认是左右分布的
paned.pack(fill=tk.BOTH, expand=1) #放到主窗口,上下左右缩放
#选择目录
def selectdirectory():
path_ = askdirectory()
tree.clear()
tree.load_path(path_ ) #为树控件加载指定的目录树
#树鼠标双击事件
def treeDoubleClick(event):
#print(event)
item = tree.tree.selection()[0]
i2=tree.tree.parent(item)
s2=""
while i2!="":
s2=tree.tree.item(i2, "text")+'\\'+s2
i2=tree.tree.parent(i2)
txt2=s2+tree.tree.item(item, "text")
if txt2[-4:]=='.txt' or txt2[-3:]=='.py':
ucode.loadfile(txt2)
tabControl2.tab(0, text=ucode.filename)
def setlabel():
tabControl2.tab(0, text=ucode.filename)
#左画面设计
ttabControl = ttk.Notebook(paned) # Create Tab Control
ttab1 = ttk.Frame(ttabControl) # Add a third tab
ttabControl.add(ttab1, text='工程目录') # Make second tab visible
paned.add(ttabControl)
paned.paneconfig(ttabControl,width=200)
tree = htk.Tree(ttab1,width=200)
tree.load_path('./') #为树控件加载指定的目录树
tree.pack(expand = 1, fill = tk.BOTH)
tree.usepop=treeDoubleClick #绑定双击事件
#在左右可调区域中创建,可上下调整区域paned2
paned2 = tk.PanedWindow(paned,orient=tk.VERTICAL, showhandle=True, sashrelief=tk.SUNKEN,width=int((winw-300)/2),sashwidth=1)
paned.add(paned2)
#tabControl = htk.ClosableNotebook(paned2) #创建Notebook
tabControl2 = ttk.Notebook(paned2)
tab = tk.Frame(tabControl2,bd=0,background='black')
tabControl2.add(tab, text='newfile.py')
#在选项卡中建立代码编辑器
ucode=ide.Codeedit(tab,fontsize=12,bg='black') #代码编辑框
tabControl2.pack(fill=tk.BOTH, expand=1)
ucode.setlabel=setlabel
ucode.outcolor='white'
ucode.outcolor2='white'
ucode.ispop=True #动态提示
paned2.add(tabControl2)
paned2.paneconfig(tabControl2,heigh=400)
root.ucb=ucode.Callback
#建立分割区域paned3
paned3 = tk.PanedWindow(paned2,orient=tk.VERTICAL, showhandle=True, sashrelief=tk.SUNKEN,width=int((winw-300)/2),bg='black',sashwidth=1)
paned2.add(paned3)
##为信息框设置一个容器
frame2=tk.LabelFrame(paned3,text='信息框',height=100)
frame2.pack(fill=tk.BOTH, expand=1)
umess=ide.PythonCMD(frame2,ipy="ipython",py="ipython ",fontsize=12,bg='#5a5a5a')
umess.pack(expand=1,fill=tk.BOTH)
paned3.paneconfig(frame2,heigh=200)
htk.ttmsg=umess.text #绑定信息输出变量,
ucode.outmess=htk.ttmsg #设置代码输出信息框
#htk.ttmsg['bg']='#7a7a7a' #输出窗底色
htk.ttmsg['fg']='white' #输出框字体颜色
htk.ttmsg['insertbackground']='magenta' #输出框光标颜色
#创建状态栏
status=htk.StatusBar(root) #建立状态栏
status.pack(side=tk.BOTTOM, fill=tk.X) #把状态栏放到最底部
status.demo()
keyvars=[g.root,g.mainmenu,g.tabControl,g.tab1,g.tab2,g.tab3,g.tab4,g.tab5,g.tab6,g.tab7,g.tab8,g.tab9]
def resetvar():
[g.root,g.mainmenu,g.tabControl,g.tab1,g.tab2,g.tab3,g.tab4,g.tab5,g.tab6,g.tab7,g.tab8,g.tab9]=keyvars
##设置菜单功能的功能
mainmenu.set('文件','执行程序',command=ucode.runpy)
mainmenu.set('文件','新建',command=ucode.newfile)
mainmenu.set('文件','打开',command=ucode.openfile)
mainmenu.set('文件','运行',command=ucode.runuc)
mainmenu.set('文件','保存',command=ucode.savefile)
mainmenu.set('文件','另存为',command=ucode.saveas)
mainmenu.set('编辑','撤销',command=ucode.undo)
mainmenu.set('编辑','重做',command=ucode.redo)
mainmenu.set('编辑','剪切',command=ucode.cut)
mainmenu.set('编辑','复制',command=ucode.copy)
mainmenu.set('编辑','粘贴',command=ucode.paste)
mainmenu.set('编辑','全选',command=ucode.selectall2)
mainmenu.set('程序','运行',command=ucode.runuc)
mainmenu.set('程序','转中文',command=ucode.pyetoc)
mainmenu.set('程序','转英文',command=ucode.pyctoe)
mainmenu.set('帮助','项目缩略图',command=root.save)
mainmenu.set('项目','项目目录',command=selectdirectory)
mainmenu.set('项目','恢复环境变量',command=resetvar)
#全局初始化
g.title=mytitle
g.root=root
g.mainmenu=mainmenu
g.ucode=ucode
g.tabControl=tabControl
g.tab1=tab #工作台
keyvars=[g.root,g.mainmenu,g.tabControl,g.tab1,g.tab2,g.tab3,g.tab4,g.tab5,g.tab6,g.tab7,g.tab8,g.tab9]
def setvar():
global keyvars
keyvars=[g.root,g.mainmenu,g.tabControl,g.tab1,g.tab2,g.tab3,g.tab4,g.tab5,g.tab6,g.tab7,g.tab8,g.tab9]
def resetvar():
global keyvars
[g.root,g.mainmenu,g.tabControl,g.tab1,g.tab2,g.tab3,g.tab4,g.tab5,g.tab6,g.tab7,g.tab8,g.tab9]=keyvars
setvar()
tabControl.ufun=resetvar
root.mainloop() #进入Tkinter消息循环
上面是程序运行结果,当在代码框输入字母i时,弹出提示框。我们现在想取消这个提示框,可以运行下面插件程序[关闭动态提示.py],关闭弹出提示框功能。
#程序名:关闭动态提示.py
import HP_global as g #建立全局数据域
g.ucode.ispop=False #关闭动态提示
执行这个插件后,再输入字母i,就没有出现弹出提示框。 上面是简单插件演示。 我们根据此原理设计了2个插件程序[小白回测2]和[行情列表]插件程序。 我们的新插件程序使用自动识别技术。如果在[小白量化中文Python研学实控系统]中运行是上面的图形,同样的程序在其他IDE中,插件程序运行结果如下。 为什么会如此?如何实现的,下篇再将。
好了,欢迎继续关注我的博客。
超越自己是我的每一步!我的进步就是你的进步!
|