代码拉取完成,页面将自动刷新
# -*- coding: utf-8 -*-
import numpy as np
from numpy import pi,sqrt
import os
import tqdm
import math
import subprocess
from calculator_gui import calculate_all
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"]=["SimHei"] #设置 中文字体
plt.rcParams["axes.unicode_minus"]=False #该语句解决图像中的“-”负号的乱码问题
from matplotlib.animation import FuncAnimation
from matplotlib.colors import LinearSegmentedColormap
import matplotlib
from matplotlib.lines import Line2D
matplotlib.use('TKAgg')
from scipy.interpolate import interp1d
import itertools
from itertools import product
import tkinter as tk
from tkinter import ttk
import copy
from multiprocessing import Pool
import multiprocessing
#from pandastable import Table
__version__ = '2.4.0' # 设置版本号
#获取路径
script_directory = os.path.dirname(os.path.abspath(__file__))
basename = os.path.basename(script_directory)
# 判断末级名称是否是_internal
if basename == "_internal": #如果运行打包的程序文件时,需要修正路径
script_directory= os.path.dirname(script_directory)
class CoilMode():
def __init__(self,modeidata=0,lin_preset=0,only_id='') -> None:
self.combo_scanning_list =[[],[]]
if lin_preset != 0:
self.only_id= only_id
self.modei=0
self.modeend=0
self.lin_preset=lin_preset
self.lin_preset_To_preset()
self.combo_scanning_list = -1
else:
global modecsv
self.Modefile=pd.read_csv(modecsv, index_col=False, encoding='GBK')
if(modeidata ==0):
self.mode=eval(self.Modefile.loc[0,'行选择'])
else:
self.mode=modeidata
print("行选择:"+str(self.mode))
self.only_id= self.mode[0]
self.modei=int(self.mode[1])-2
self.modeend=int(self.mode[2])-2
coil_layout=[]
for i in range(self.modei,self.modeend+1):
coil_layout.append({'匝数或外径模式选择(0or1)':self.load('匝数或外径模式选择(0or1)',i), '漆包线材料(CuorAl)':self.load('漆包线材料(CuorAl)',i),'漆包线线径(mm)':self.load('漆包线线径(mm)',i), '漆层厚度(um)':self.load('漆层厚度(um)',i),'线圈长度(mm)':self.load('线圈长度(mm)',i),'匝径start':self.load('匝径start',i),'匝数幂衰减系数':self.load('匝数幂衰减系数',i),'线圈数量':self.load('线圈数量',i),'脉宽(pw)':self.load('脉宽(pw)',i),'脉宽幂递增系数':self.load('脉宽幂递增系数',i), '关断策略偏移(mm)':self.load('关断策略偏移(mm)',i) } )
Secondary_parameters = eval(self.Modefile.loc[0,'次要参数'])
self.lin_preset = {
'Secondary_parameters':Secondary_parameters,
'coil_layout':coil_layout, #线圈参数
'L_coil1':self.load('隔板长度(mm)'), #隔板 mm
'Inner_diameter':self.load('支架直径(mm)'), #或者可以称之为 线圈内直径 mm
"R_pow" : self.load('外部阻抗(esr)'), # 电源电阻
"U0": self.load('电容耐压值(V)'), # 初始电压
"C" : self.load('电容值(uf)'), # 电容
"slug_R" : self.load('子弹直径(mm)'), #子弹直径
"slug_length" : self.load('子弹长度(mm)'), #子弹长度
"m" :self.load('子弹质量(g)'), #子弹质量
"v0": self.load('初始速度(mps)'), # 初始速度
"saturationB_T":self.load('饱和磁导(T)'), #饱和磁导
}
#################################################参数化扫描
#参数化扫描 线圈参数
for i,layout in zip(range(len(self.lin_preset["coil_layout"])) ,self.lin_preset["coil_layout"]) :
for key, value in layout.items():
if isinstance(value, str) :
if isinstance(eval(value), list):
evalvalue=eval(value)
self.combo_scanning_list[0].append([i,key])
if key=='线圈数量' or key=='漆包线材料(CuorAl)' or key=='匝数或外径模式选择(0or1)': #线圈数量项目要取整
self.combo_scanning_list[1].append( list(set([ int(evalvaluei) for evalvaluei in np.linspace(evalvalue[0], evalvalue[1], evalvalue[2], endpoint=True) ] )) )
else:
self.combo_scanning_list[1].append( np.linspace(evalvalue[0], evalvalue[1], evalvalue[2], endpoint=True) )
elif isinstance(eval(value), tuple):
evalvalue=list(eval(value))
#print(evalvalue)
self.combo_scanning_list[0].append([i,key])
self.combo_scanning_list[1].append( evalvalue )
else: #其他为float类型即可
layout[key] = float(value)
#参数化扫描 非线圈参数
for key, value in self.lin_preset.items():
if(key != "coil_layout") :
if isinstance(value, str) :
if isinstance(eval(value), list):
evalvalue=eval(value)
self.combo_scanning_list[0].append([-1,key])
self.combo_scanning_list[1].append( np.linspace(evalvalue[0], evalvalue[1], evalvalue[2], endpoint=True) )
elif isinstance(eval(value), tuple):
evalvalue=list(eval(value))
self.combo_scanning_list[0].append([-1,key])
self.combo_scanning_list[1].append( evalvalue )
else:
self.lin_preset[key] = float(value)
self.cartesian_product = list(product(*self.combo_scanning_list[1])) #笛卡尔积
#print(self.combo_scanning_list)
def lin_preset_To_preset(self):
#print(self.lin_preset)
#print('\n')
#####coil_layout 朝上获取最近的有效数值
for i in range(len(self.lin_preset['coil_layout'])):
for key, value in self.lin_preset['coil_layout'][i].items():
self.lin_preset['coil_layout'][i][key] = float(value)
if math.isnan(self.lin_preset['coil_layout'][i][key] ) :
#print(f"i:{i},key:{key},value:{value},{self.lin_preset['coil_layout'][i-1][key]}")
self.lin_preset['coil_layout'][i][key]= self.lin_preset['coil_layout'][i-1][key]
#一些数量项目要取整
for coil_l in self.lin_preset['coil_layout'] :
coil_l['线圈数量'] = int(coil_l['线圈数量'])
coil_l['漆包线材料(CuorAl)'] = int(coil_l['漆包线材料(CuorAl)'])
coil_l['匝数或外径模式选择(0or1)'] = int(coil_l['匝数或外径模式选择(0or1)'])
coil_number_calculate=int(sum( int(coil_l['线圈数量']) for coil_l in self.lin_preset['coil_layout'] ))
#计算炮管长度
paoguan_length_mm = 0
for coil_l in self.lin_preset['coil_layout'] :
paoguan_length_mm+=coil_l['线圈数量']*(coil_l['线圈长度(mm)']+ self.lin_preset['L_coil1'] )
##print(f'炮管长度:{paoguan_length_mm}')
if self.lin_preset['m'] == 0: #启用自动计算质量功能
mypreset_m = self.calculate_cylinder_mass( float(self.lin_preset['slug_R']) , float(self.lin_preset['slug_length']),self.lin_preset['Secondary_parameters']['子弹密度(g/cm3)'] )
else :
mypreset_m = float(self.lin_preset['m']*1e-3)
if self.lin_preset['v0'] == 0:
mypreset_v0 = 0.01
else :
mypreset_v0 = float(self.lin_preset['v0'])
#print(f'183:{self.lin_preset}')
self.preset = {
'Secondary_parameters':self.lin_preset['Secondary_parameters'],
"R_mos" :0*1e-3, # MOSFET电阻
"V_dio": 1.7, # 二极管电压(可能是正向压降)
"coil_number" : coil_number_calculate , # 线圈数量
"paoguan_length" : paoguan_length_mm *1e-3 , # 炮管长度
'coil_layout':self.lin_preset['coil_layout'], #线圈参数
'L_coil1':self.lin_preset['L_coil1']*1e-3, #隔板 mm
'Inner_diameter':self.lin_preset['Inner_diameter']*1e-3, #或者可以称之为 线圈内直径 mm
"R_pow" : self.lin_preset['R_pow']*1e-3, # 电源电阻
"U0": self.lin_preset['U0'], # 初始电压
"C" : self.lin_preset['C']*1e-6, # 电容
"slug_R" : self.lin_preset['slug_R']*1e-3, #子弹直径
"slug_length" : self.lin_preset['slug_length']*1e-3, #子弹长度
"m" : mypreset_m, #子弹质量
"v0": mypreset_v0, # 初始速度
"saturationB_T":self.lin_preset['saturationB_T'], #饱和磁导
}
##################################
# 初始化字典的列表,以便最后输出时序/位置顺序
self.ts_control = [{'num': i,'导通时刻': 10000, '脉宽': -1,'S_td': 10000, 'S_pw': -1 , 'v0': -1 , 'v1': -1 } for i in range(self.preset["coil_number"])] #时序
#计算结果
def calculate_result(self,coils,yss,rs,Coil_weight_list,Coil_R=[],show_extra_information = '不显示额外信息' ):
U = yss[-3]
v = yss[-2]
t = yss[-1]
self.dEk = 0.5*self.preset["m"]*(v[-1]**2-self.preset["v0"]**2) #
result_use_E = 0.5*(self.preset['C']*(self.preset["U0"]**2-U[-1]**2))
self.eff = self.dEk/(result_use_E) *100
self.v_result = v[-1]
coil_maxAi=[] #最大电流
for i in range(self.preset["coil_number"]):
coil_maxAi.append(max(yss[i]))
self.coil_maxA = max(coil_maxAi)
m_C=(0.5*self.preset['C']*self.preset["U0"]**2)/self.preset["Secondary_parameters"]['电容重量储能密度(j/g)']
Coil_weight_all = sum(Coil_weight_list)
self.m_All=Coil_weight_all+m_C
self.myresult=f'初位置:{rs[0]*1e+3:.1f}mm |出速:{self.v_result:.2f}m/s |效率:{self.eff:.1f}% |Δ动能:{self.dEk:.1f}J |动子:{self.preset["slug_R"]*1000:.1f}*{self.preset["slug_length"]*1000:.1f},{self.preset["m"]*1000:.2f}g |电容:{self.preset["U0"]:.0f}V*{self.preset["C"]*1e+6:.0f}uf,{self.preset["R_pow"]*1e+3:.0f}mΩ |支架直径:{self.preset["Inner_diameter"]*1000:.1f}mm |总重:{Coil_weight_all:.1f}+{m_C:.1f}={self.m_All:.1f}g |最大电流:{self.coil_maxA:.1f}A ' #|线圈升温:{delta_T:.2f}°C
delta_T_list =[]
if Coil_R != []: #仅在非扫描模式下额外计算升温
coili_useE=[sum([ yss[i][j]**2*Coil_R[i]*(t[j]-t[j-1]) for j in range(1,len(t)) ]) for i in range(self.preset["coil_number"])]
print(f'\n各线圈的电阻耗能: {[ round(e,2) for e in coili_useE]} J')
print(f'线圈的总电阻耗能: {sum(coili_useE):.2f} J')
delta_T_list = [ EEi / (wei * 0.385) for EEi,wei in zip(coili_useE,Coil_weight_list) ]
#########
if show_extra_information == '显示额外信息':
Vb_E=[sum([ yss[i][j]*v[j]*coils[i].Fmodel(rs[j])*(t[j]-t[j-1]) for j in range(1,len(t)) ]) for i in range(self.preset["coil_number"])]
print(f'\n弹丸动能增量: {[ round(e,2) for e in Vb_E]} J')
print(f'弹丸动能增量: {sum(Vb_E):.2f} J')
#计算驱动损耗
xxx = [0 ,60 ,120, 180 , 240 , 300 , 360 , 420 ,480 ,600 ,800 ]
yyy = [0.4 ,1.5 ,2 , 2.3 , 2.6 , 3 , 3.4 ,3.6 ,3.9 ,5 ,7 ]
Vf=interp1d(xxx, yyy, kind='linear', bounds_error=False, fill_value="extrapolate") #二极管 电流-压降 曲线
mos_useE=[sum([ yss[i][j]*(Vf(yss[i][j])*2)*(t[j]-t[j-1]) for j in range(1,len(t)) ]) for i in range(self.preset["coil_number"])]
print(f'\n普通半桥 igbt 总损耗:{sum(mos_useE):.2f} J')
'''#线圈防逆二极管使用俩并联均流
mos_useE=[sum([ yss[i][j]*(Vf(yss[i][j])*2+ Vf(yss[i][j]/2))*(t[j]-t[j-1]) for j in range(1,len(t)) ]) for i in range(self.preset["coil_number"])]
print(f'半桥阵列 igbt+二极管 总损耗:{sum(mos_useE):.2f} J')
Rpow=[sum([ yss[i][j]**2*self.preset["R_pow"]*(t[j]-t[j-1]) for j in range(1,len(t)) ]) for i in range(self.preset["coil_number"])]
E0=result_use_E - (sum(mos_useE) + sum(coili_useE) + sum(Vb_E) + sum(Rpow) )
print(f'E0:{E0:.2f} J')
η_all=[]
for ci in range(self.preset["coil_number"]):
m = self.preset["m"]
Rd = coils[ci].R
v1= 193.66#v[-1]
v0= v[0]
k = coils[ci].Fmodel( coils[ci].r - 0.5*self.preset["slug_length"] )
x = 390*1e-3#self.preset['paoguan_length']
η = 1/( 1+ m*Rd*(v1-v0)/( k**2*x) )
print( f'{ci},理论最大效率:{η*100}%')
η_all.append(η)'''
return delta_T_list
#输入直径,长度来计算子弹质量
def calculate_cylinder_mass(self,diameter_mm, length_mm, density_g_per_cm3=7.85):
# 将直径和长度从毫米转换为厘米
diameter_cm = diameter_mm / 10
length_cm = length_mm / 10
# 计算半径
radius = diameter_cm / 2
# 计算体积(单位:立方厘米)
volume = math.pi * radius ** 2 * length_cm
# 计算质量(单位:克)
mass_g = density_g_per_cm3 * volume
mass = round(mass_g ,2)
return mass*1e-3 #单位kg
def load(self,field,ii=-1):
if ii==-1: #默认情况下为modei
ii=self.modei
getValue=self.Modefile.loc[ii,field]
return getValue
#保存数据 以便进Maxwell验证
def save(self,coils,td,pw,myresult,stop_time):
self.Modefile.loc[self.modei,"result"]= str(myresult)
#CoilModedict是转换成给Maxwell使用的 数据
CoilModedict={}
for key, value in self.lin_preset.items():
#print(key)
if key != 'Secondary_parameters' and key != 'coil_layout' and key != 'saturationB_T':
CoilModedict[key] = value
CoilModedict['T'] = stop_time
CoilModedict['coil_number'] =self.preset["coil_number"]
CoilModedict['Ns'] = [coili.N for coili in coils ]
CoilModedict['Rs'] = [coili.R*1e+3 for coili in coils ]
CoilModedict['Outer_diameter'] = [coili.Outer_d*1e+3 for coili in coils ]
s_init=td[0]
td2=[ -s_init+td[i] for i in range(self.preset["coil_number"])]
CoilModedict['s_init'] = s_init *1e+3
CoilModedict['td'] = [td2[i]*1e+3 for i in range(self.preset["coil_number"]) ]
CoilModedict['pw'] = [pw[i]*1e+3 for i in range(self.preset["coil_number"]) ]
self.Modefile.loc[self.modei, '行选择'] = str(CoilModedict)
# 将修改后的数据保存进CSV文件
global modecsv
self.Modefile.to_csv(modecsv, index=False, encoding='GBK')
#线圈数据
class Coil():
def __init__(self,i,magpara,Mode) -> None:
N,L,M,R,length,Outer_d,coil_loc = magpara
self.μ0 = 4 * pi * 1e-7
self.i = i #线圈编号
self.N = N #线圈匝数
self.L = L #线圈自感
self.M = M #线圈互感
self.R = R #线圈电阻
self.length =length #线圈长度
self.Inner_d = Mode.preset['Inner_diameter'] #线圈内直径
self.Outer_d = Outer_d #线圈外直径
self.r = coil_loc #线圈位置s
self.tdi = Mode.td[i] #线圈导通时刻
self.pwi = Mode.pw[i] #线圈导通持续时间
self.slug_halflength = (Mode.preset['slug_length']/2)
r = Mode.preset['slug_R']/2 #弹丸半径
self.S = pi*r**2 #弹丸端面的面积
self.coil_M = Mode.preset['saturationB_T'] /self.μ0 #弹丸磁化强度 !
#print("Coil:",self.i,self.N,self.Ls*1e+6,self.Ms*1e+6,self.R*1e+3)
def BFieldCoil(self, z, current=1): #根据位置 计算磁感应强度!(current=1 代表工作在 单位电流时的情况)
L=self.length
a=L/2
r2=self.Outer_d/2
r1=self.Inner_d/2
R=r2-r1
def F(x):
return x * math.log((sqrt(x ** 2 + r2 ** 2) + r2) /
(sqrt(x ** 2 + r1 ** 2) + r1))
return ( self.μ0*self.N*current/(2*L*R) ) * (F(z+a)-F(z-a))
def calculate_F(self,D): #根据位置与磁感应强度差 计算弹丸受力!
B0=self.BFieldCoil(D+self.slug_halflength)
B1=self.BFieldCoil(D-self.slug_halflength)
ΔB= B0-B1
return self.coil_M*ΔB*self.S
def Fmodel(self,r):
#r-self.r 是弹丸中心到线圈中心的距离
return self.calculate_F(r-self.r) #/ self.N'''
#子弹运动
class Slug_move():
def __init__(self,Mode,coils,step_select) -> None:
self.r=coils[0].tdi #初始弹丸位置r为td[0],是个负数
self.R_all= -self.r + coils[-1].r+coils[-1].length # 总加速距离
self.drset= Mode.preset["Secondary_parameters"]['默认后续微元步进']*1e-3 #0.2 *1e-3
if step_select != '使用默认后续微元步进' :
self.drset= float(step_select) *1e-3
drlist_head_eval = eval(Mode.preset["Secondary_parameters"]['初始微元步进切分'] ) #eval('[[0.001]*10 ,[0.01]*10,[0.1]*80]')
drlist_head=[item*1e-3 for sublist in drlist_head_eval for item in sublist]
n=int((self.R_all-sum(drlist_head))/self.drset)
self.drlist= drlist_head + [self.drset]*n
#print(self.drlist)
self.t=0
self.Mode = Mode
self.coils = coils
self.SwitchResult=[-1 for coil in self.coils] #计算各线圈的导通状态
self.FmodelResult=[0 for coil in self.coils ] #计算各线圈的单位电流受力
self.leftopencoil = 0 #最左侧导通线圈编号
self.lastopencoil = 0 #最右侧导通线圈编号
#计算驱动损耗
xxx = [0 ,60 ,120, 180 , 240 , 300 , 360 , 420 ,480 ,600 ,800 ]
yyy = [0.4 ,1.5 ,2 , 2.3 , 2.6 , 3 , 3.4 ,3.6 ,3.9 ,5 ,7 ]
#self.Vf=interp1d(xxx, yyy, kind='linear', bounds_error=False, fill_value="extrapolate") #二极管 电流-压降 曲线
#RK4(4阶龙格库塔法),算出下一个 ys
def rk4_step(self,equ,ys,dr):
k1 = equ(ys)
k2 = equ(ys+k1*dr/2)
k3 = equ(ys+k2*dr/2)
k4 = equ(ys+k3*dr)
return ys+dr*(k1+2*k2+2*k3+k4)/6
# main
def MainEquation(self,ys):
devi = np.zeros_like(ys)
## ys = [I1,I2 ... INcoils,U,v,t]
ys[:len(self.coils)] = np.where(ys[:len(self.coils)]>0,ys[:len(self.coils)],0)
U,v,self.t = ys[-3:]
self.v=v
#现在只动态计算动子附近的线圈
for i in range(len(self.coils)):
if i > 0 and ys[i]>0 :
self.leftopencoil = i-1
break
left = self.leftopencoil
right = self.lastopencoil+2
if right > len(self.coils):
right = len(self.coils)
self.SwitchResult[left:right] = [self.StateModel(self.coils[i]) for i in range(left,right)] #动态计算各线圈的导通状态
self.FmodelResult[left:right] = [self.coils[i].Fmodel(self.r) for i in range(left,right)] #动态计算各线圈的单位电流受力
coilsneed = [ self.coils[i] for i in range( self.leftopencoil ,self.lastopencoil+1) ]
#print([ i for i in range( self.leftopencoil ,self.lastopencoil+1) ])
equations = np.zeros((len(coilsneed),len(coilsneed)+1))
V_pow = U - sum([self.SwitchResult[coil.i]*ys[coil.i] for coil in coilsneed])*self.Mode.preset["R_pow"]
for i,coil2i in zip(range(len(coilsneed)),coilsneed):
if self.SwitchResult[coil2i.i]>0 or ys[coil2i.i]>0:
if i > 2:
equations[i][i-2] = coil2i.M['-2']
if i > 1:
equations[i][i-1] = coil2i.M['-1']
equations[i][i] = coil2i.L
if i < len(coilsneed)-1:
equations[i][i+1] = coil2i.M['1']
if i < len(coilsneed)-2:
equations[i][i+2] = coil2i.M['2']
#
'''equations[i][-1] = - ys[coil2i.i]*coil2i.R \
+ self.SwitchResult[coil2i.i]*V_pow \
- 2*self.Vf(ys[coil2i.i])\
- v*self.FmodelResult[coil2i.i] '''
equations[i][-1] = - ys[coil2i.i]*coil2i.R \
+ self.SwitchResult[coil2i.i]*V_pow \
-2*self.Mode.preset["V_dio"] \
- v*self.FmodelResult[coil2i.i]
'''equations[i][-1] = - ys[coil2i.i]*(coil2i.R + 2 * self.Mode.preset["R_mos"]) \
+ self.SwitchResult[coil2i.i]*V_pow \
+ (self.SwitchResult[coil2i.i]-1)*self.Mode.preset["V_dio"] \
- v*self.FmodelResult[coil2i.i]'''
else:
equations[i][i] = 1
devi[coilsneed[0].i:coilsneed[-1].i+1] = (np.linalg.solve(equations[:,:-1],equations[:,-1]))/v
devi[-3] = (- sum([self.SwitchResult[coil.i]*ys[coil.i] for coil in coilsneed]) / self.Mode.preset["C"])/v #dU/dr
devi[-2] = (sum([ys[coil.i]*self.FmodelResult[coil.i] for coil in coilsneed])/self.Mode.preset["m"])/v #dv/dr
devi[-1] = 1/v #
return devi #这里输出的是dys/dr,后续在rk4那乘以dr就能得到dys,再ys+dys就能求出下一步的ys (ys为各种变量如U,v,i等)
def main(self):
rs = []
rs.append(self.r)
ys = np.zeros(self.Mode.preset["coil_number"] + 4)
ys[-3] = self.Mode.preset["U0"]
ys[-2] = self.Mode.preset["v0"]
ys[-1] = 0 #初始t=0
yss = []
yss.append(ys)
for dr in tqdm.tqdm(self.drlist):
ys = self.rk4_step(self.MainEquation,ys,dr) #,(self.coils,self.Mode.preset)
yss.append(ys)
self.r = self.r+dr
rs.append(self.r)
yss = np.array(yss).T #.T 是把列变成行
rs = np.array(rs)
return yss,rs
#######################线圈i状态切换(导通/回收)
def StateModel(self,coil): #Switch函数 #判断线圈coil.i是否导通
if self.Mode.ts_control[coil.i]['脉宽'] != -1: #若 脉宽 已被记录 则表示线圈已经完成任务了。
return -1
if coil.tdi <= self.r < coil.tdi+coil.pwi : #判断子弹进入了 线圈i在导通区间
if self.Mode.ts_control[coil.i]['导通时刻'] ==10000:
self.Mode.ts_control[coil.i]['导通时刻'] = round(self.t*1e+6,2) #记录线圈i导通起始时刻时的时刻(仅记录一次)
self.Mode.ts_control[coil.i]['S_td'] = round(self.r*1e+3,2) #记录线圈i导通起始时刻时的距离(仅记录一次)
self.Mode.ts_control[coil.i]['v0'] = round(self.v,2)
self.lastopencoil = coil.i #动态计算的右侧线圈编号
return 1 # 线圈i 导通阶段
else:
if (self.r >= coil.tdi+coil.pwi and self.Mode.ts_control[coil.i]['脉宽'] == -1 ) :
self.Mode.ts_control[coil.i]['脉宽'] = round(self.t*1e+6 - self.Mode.ts_control[coil.i]['导通时刻'] ,2)#记录线圈i结束时的持续时间(仅记录一次)
self.Mode.ts_control[coil.i]['S_pw'] = round(self.r*1e+3 -self.Mode.ts_control[coil.i]['S_td'] ,2) #记录线圈i结束时的持续距离(仅记录一次)
self.Mode.ts_control[coil.i]['v1'] = round(self.v,2)
return -1
#多进程扫描
def worker(Z0):
#print(f'593,Z0:{Z0}')
Mode=CoilMode(0,Z0[2])
Mode.lin_preset_To_preset()
#print(Mode.preset)
Coil_wires,Coil_N,Coil_L,Coil_M,Coil_R,Coil_length,Coil_Outer_diameter,coil_location,pw,pwk,Coil_weight_list =calculate_all('参数化扫描','不计算互感', Mode.preset['Inner_diameter'],Mode.preset['L_coil1'],Mode.preset['coil_layout'])
Mode.td=[ ( -pw[i]+pwk[i] -0.5*(Mode.preset["slug_length"]) + coil_location[i] ) for i in range(Mode.preset["coil_number"])] # 当 弹丸位置 到 td位置 时线圈i导通 (+0代表 当弹丸前端到线圈中心时 开始回收)
Mode.pw=pw
coils = [ Coil(i,(Coil_N[i],Coil_L[i],Coil_M[i],Coil_R[i],Coil_length[i] ,Coil_Outer_diameter[i],coil_location[i] ) ,Mode) for i in range(Mode.preset["coil_number"])]
yss,rs=Slug_move(Mode,coils,1).main()
Mode.calculate_result(coils,yss,rs,Coil_weight_list)
##[ci,int(len(cartesian_now)/14),14,len(cartesian_now)]
print(Z0[0])
return [ Mode.dEk,Mode.coil_maxA,Z0[1] ,Mode.eff,Mode.v_result,Mode.m_All , str(Mode.lin_preset)]
# ------- * 参数化扫描 * ---------
def scanning_main(Mode):
global combo_Mcaulate_select
global combo_paoguan_select
Z = []
printdata=[]
cartesian_now = Mode.cartesian_product
try:
Z_old=''
global combo_selectfile
folder_name = f'{script_directory}\\scanResultFile'
# 检查文件夹是否存在
if not os.path.exists(folder_name):
# 如果不存在,则创建文件夹
os.makedirs(folder_name)
print(f"文件夹 {folder_name} 已创建")
else:
print(f"文件夹 {folder_name} 已存在")
scanning_file= f'{script_directory}\\scanResultFile\\{str(combo_selectfile.get())}_{Mode.only_id}'
# 打开文件以读取
with open(scanning_file, 'r') as file:
Z_old = eval(file.read() )
Z = Z_old
list1 = [ str(li) for li in cartesian_now]
cartesian_p_old = [p[2] for p in Z_old]
list2 = [ str(li) for li in cartesian_p_old]
# 使用列表推导式去除交集元素
cartesian_now = [ eval(li) for li in [x for x in list1 if x not in list2] ]
except:
pass
processes_Number = Mode.lin_preset["Secondary_parameters"]["参数扫描进程数"]
scan_cartesian=[]
real_preset_coil_layout= copy.deepcopy( Mode.lin_preset["coil_layout"] ) # 对 coil_layout 进行深复制
for ci in range(len(cartesian_now)) :
cartesian_p = cartesian_now[ci]
#更换参数
Mode.lin_preset["coil_layout"] = copy.deepcopy(real_preset_coil_layout)
for i,name in zip(range(len(Mode.combo_scanning_list[0])),Mode.combo_scanning_list[0]):
if name[0] !=-1 : #参数化更新线圈参数
Mode.lin_preset["coil_layout"][name[0]][name[1]]=cartesian_p[i]
else: #参数化更新非线圈参数
Mode.lin_preset[name[1]] =cartesian_p[i]
Mode.lin_preset_To_preset()
scan_cartesian.append( [ f'{ci}/{len(cartesian_now)}', cartesian_p , copy.deepcopy( Mode.lin_preset)] )
if __name__ == '__main__':
with Pool( processes_Number ) as p: # 创建一个包含 processes_Number 个进程的进程池
result = p.map(worker, scan_cartesian ) # 使用map方法并行执行
Z = Z+result
# 保存文件
with open(scanning_file, 'w') as file:
file.write(str(Z))
#######################################2d表1'''
x = np.array([p[0] for p in Z])
y = np.array([p[1] for p in Z])
mode_list = np.array([p[6] for p in Z])
p_list = np.array([p[2] for p in Z])
#print(mode_list)
# 创建一个图形和轴
fig, ax = plt.subplots()
ax.set_xlabel(f"Δ动能(J) 行波加速模拟器 版本号为:{__version__} 开源地址:https://www.kechuang.org/t/90279")
ax.set_ylabel('最大电流(A)')
ax.set_title(scanning_file)
# 绘制散点图
scatter = ax.scatter(x, y, color='blue', alpha=0.5)
annotation = [ax.annotate(f'({[round(zz,3) for zz in zi[2]]}),{zi[3]:.1f}% |{zi[4]:.1f}m/s |{zi[5]:.1f}g', (zi[0], zi[1]) , visible=False) for zi in Z ] # 标注文本和位置
# 初始化最近点的线对象(初始时不显示)
nearest_line = Line2D([], [], color='red', marker='o', markersize=10, lw=2)
ax.add_line(nearest_line)
nearest_line.set_visible(False)
# 用于存储最近点的索引
global nearest_index
nearest_index = None
def on_move(event):
# 检查鼠标是否在图上
if event.inaxes == ax and annotation[0].get_visible()==False:
for ann in annotation:
ann.set_visible(True)
# 强制重新绘制图形
fig.canvas.draw_idle()
elif event.inaxes != ax and annotation[0].get_visible()==True:
for ann in annotation:
ann.set_visible(False)
# 强制重新绘制图形
fig.canvas.draw_idle()
if event.inaxes == ax:
# 计算所有点到鼠标位置的距离
distances = np.sqrt((x - event.xdata) ** 2 + ( max(x)/max(y)*( y - event.ydata) ) ** 2)
#print(distances)
global nearest_index
# 找到最近的点
if len(distances) > 0:
nearest_index = np.argmin(distances)
nearest_x = [x[nearest_index]]
nearest_y = [y[nearest_index]]
# 更新线对象以显示最近的点
nearest_line.set_data(nearest_x, nearest_y)
nearest_line.set_visible(True)
# 强制重新绘制图形
fig.canvas.draw_idle()
else:
nearest_line.set_visible(False)
def on_click(event):
global nearest_index
if event.inaxes == ax and str(event.button) == 'MouseButton.RIGHT':
not_scanning_main(CoilMode(0, eval(mode_list[nearest_index]), f'({[round(zz,3) for zz in p_list[nearest_index]]})' ) ) #str( )
# 连接鼠标移动事件到回调函数
fig.canvas.mpl_connect('motion_notify_event', on_move)
# 连接鼠标点击事件
fig.canvas.mpl_connect('button_press_event', on_click)
# 显示图形
plt.show()
# ------- * 非参数扫描* ---------
def not_scanning_main(Mode):
global combo_Mcaulate_select
global combo_step_select
global combo_extra_information_select
global combo_showplt
Coil_wires,Coil_N,Coil_L,Coil_M,Coil_R,Coil_length,Coil_Outer_diameter,coil_location,pw,pwk,Coil_weight_list =calculate_all('非参数化扫描',combo_Mcaulate_select.get(), Mode.preset['Inner_diameter'],Mode.preset['L_coil1'],Mode.preset['coil_layout'])
Mode.td=[ ( -pw[i]+pwk[i] -0.5*(Mode.preset["slug_length"]) + coil_location[i] ) for i in range(Mode.preset["coil_number"])] # 当 弹丸位置 到 td位置 时线圈i导通 (+0代表 当弹丸前端到线圈中心时 开始回收)
Mode.pw=pw
coils = [ Coil(i,(Coil_N[i],Coil_L[i],Coil_M[i],Coil_R[i],Coil_length[i] ,Coil_Outer_diameter[i],coil_location[i] ) ,Mode) for i in range(Mode.preset["coil_number"])]
yss,rs=Slug_move(Mode,coils,combo_step_select.get()).main()
U = yss[-3]
v = yss[-2]
t = yss[-1]
delta_T_list=Mode.calculate_result(coils,yss,rs,Coil_weight_list,Coil_R, combo_extra_information_select.get())
#时序缩放与保存,(使用四舍五入)
tdjs=[round(i['导通时刻']*Mode.preset["Secondary_parameters"]['时序放缩系数']) for i in Mode.ts_control ]
pwjs=[round(i['脉宽']*Mode.preset["Secondary_parameters"]['时序放缩系数']) for i in Mode.ts_control ]
td_dif = [tdjs[0]] + [tdjs[i] - tdjs[i-1] for i in range(1, len(tdjs))]
td_pw = [tdjsi + pwjsi for tdjsi, pwjsi in zip(tdjs, pwjs)]
tdpw_dif=[td_pw[0]] + [td_pw[i] - td_pw[i-1] for i in range(1, len(td_pw))]
tdpwall = sorted(tdjs + td_pw )
tdpwall_dif=[tdpwall[0]] + [tdpwall[i] - tdpwall[i-1] for i in range(1, len(tdpwall))]
tdpwjs=str([tdjs,pwjs,td_dif,tdpw_dif,tdpwall_dif])
#转化为c语言可直接使用的二维数组
tdpw_c=str([tdjs,pwjs,td_dif,tdpw_dif])
tdpw_c = tdpw_c.replace('[', '{')
tdpw_c = tdpw_c.replace(']', '}')
print("\n时序:\n")
print(tdpw_c)
try :
Mode.Modefile.loc[Mode.modei, 'Tjson'] = tdpwjs #输出时序
Mode.Modefile.loc[Mode.modei, 'T_C'] = tdpw_c #输出时序
Mode.Modefile.loc[Mode.modei, 'T'] = round(t[-1]*1e+3 +0.2,2) #保存总加速时间(maxwell中的stop time)
#Mode.Modefile.loc[Mode.modei, '子弹质量(g)'] = round(Mode.preset["m"]*1e+3 ,2) #保存总加速时间(maxwell中的stop time)
#将数据保存进 mode.csv
Mode.save(coils,Mode.td,Mode.pw ,Mode.myresult,round(t[-1]*1e+3 +0.2,2)) #保存数据
print(f"\n 成功保存数据\n")
except Exception as e:
print(f"\n 注意! 未能成功进行数据保存,可能是由于先前wps文件未关闭! {e}\n")
try :
global modecsv
#用wps打开mode.csv
subprocess.Popen(Mode.preset["Secondary_parameters"]['wps地址'] +' '+modecsv )
print(f"\n 成功打开wps \n")
except Exception as e:
print(f"\n 注意! 未能成功打开wps,可能是未安装wps! {e}\n")
# ------- * 图表展示 * ---------
fig=plt.figure()
bx5 = fig.add_subplot(311)
bx5.set_ylabel("动子运动")
bx5.set_title(f'唯一id:{Mode.only_id} \n' +Mode.myresult)
# 定义一个函数,用于处理鼠标移动事件
def on_move(event):
if event.inaxes == bx5 or event.inaxes == bx1: # 检查事件是否发生在特定的子图ax1上
#print(f'Mouse position on ax1: ({event.xdata:.2f}, {event.ydata:.2f})')
global slug_r_glaobal
slug_r_glaobal = event.xdata*1e-3
else :
slug_r_glaobal = -1000
# 连接mouse_move事件到处理函数
bx5.figure.canvas.mpl_connect('motion_notify_event', on_move)
bx1 = fig.add_subplot(312, sharex = bx5)
bx1.set_ylabel("线圈电流 / A")
bx2 = fig.add_subplot(337, sharex = bx5)
bx2.set_ylabel("力 / N")
bx3 = fig.add_subplot(338, sharex = bx5)
bx3.set_ylabel("电容电压 / V")
bx4 = fig.add_subplot(339, sharex = bx5)
bx4.set_ylabel("动子速度 / m/s")
bx3.set_xlabel(f"位置 / mm 行波加速模拟器 版本号为:{__version__} 开源地址:https://www.kechuang.org/t/90279")
r_mm=np.array(rs)*1000
for i in range(Mode.preset["coil_number"]):
bx1.plot(r_mm,yss[i])
tdnp=np.array( [ round(tdi*1000,2) for tdi in Mode.td] )
pwnp=np.array( [ round(pwi*1000,2) for pwi in Mode.pw] )
ednp=tdnp+pwnp
coil_loc=np.array( [ round(coili.r*1000,2) for coili in coils] )
coil_num = [i for i in range(Mode.preset["coil_number"])]
cnumnp=np.array( coil_num )
#对电流图做标记
for tdi,edi,coil_loci,cnumi in zip(tdnp, ednp,coil_loc,cnumnp):
bx1.text(edi, max(yss[cnumi]), str(cnumi), color='green', ha='center', va='bottom') #, va='bottom'
bx1.text(coil_loci, 0, str(cnumi), color='blue', ha='center') #, va='bottom'
###########
#bx2.plot(r_mm[1:],(v[1:]*(v[1:]-v[:-1])/ (rs[1:]-rs[:-1]) )*Mode.preset["m"]) #f=ma ,计算力的第二种方法,a=v*dv/dr,a=dv/dt
bx2.plot(r_mm[1:],((v[1:]-v[:-1])/ (t[1:]-t[:-1]) )*Mode.preset["m"]) #f=ma ,计算力的第二种方法,a=v*dv/dr,a=dv/dt
bx3.plot(r_mm,U)
bx4.plot(r_mm,v, color='red')
############ 画动画
#画炮管
xxx=[r_mm[0],r_mm[-1]]
yyy=[1000*Mode.preset['Inner_diameter']/2,1000*Mode.preset['Inner_diameter']/2]
bx5.plot(xxx,yyy, 'k--')
xxx=[r_mm[0],r_mm[-1]]
yyy=[-1000*Mode.preset['Inner_diameter']/2,-1000*Mode.preset['Inner_diameter']/2]
bx5.plot(xxx,yyy, 'k--')
textmaxy=1000*coils[0].Outer_d/2 +6
#设置y轴边界
text_ylim=textmaxy+8
bx5.set_ylim(-text_ylim, text_ylim)
bx5.text(r_mm[0]-4, textmaxy, '升温:', fontsize=8,ha='right')
bx5.text(r_mm[0]-4, textmaxy-4, '电流:', fontsize=8,ha='right')
bx5.text(r_mm[0]-4, -textmaxy+4, '线径:', fontsize=8,ha='right')
bx5.text(r_mm[0]-4, -textmaxy+0, '匝数:', fontsize=8,ha='right')
bx5.text(r_mm[0]-4, -textmaxy-4, '外径:', fontsize=8,ha='right')
bx5.text(r_mm[0]-4, -textmaxy-8, '脉宽:', fontsize=8,ha='right')
###画线圈
for coili,wirei,delta_Ti in zip(coils,Coil_wires,delta_T_list):
Coil_Odi = coili.Outer_d*1000
Coil_lengthi = coili.length*1000
coil_loci = coili.r*1000
xxx=[coil_loci-0.5*Coil_lengthi ,coil_loci-0.5*Coil_lengthi ,coil_loci+0.5*Coil_lengthi ,coil_loci+0.5*Coil_lengthi ,coil_loci-0.5*Coil_lengthi]
yyy=[-0.5*Coil_Odi ,0.5*Coil_Odi ,0.5*Coil_Odi ,-0.5*Coil_Odi ,-0.5*Coil_Odi]
bx5.plot(xxx,yyy, 'k-', color='red')
bx5.text(coil_loci, textmaxy, f'{delta_Ti:.1f}', fontsize=8,ha='center')
bx5.text(coil_loci, 0, f'{int(coili.i)}', fontsize=8,ha='center')
bx5.text(coil_loci, -textmaxy+4, f'{wirei}', fontsize=8,ha='center')
bx5.text(coil_loci, -textmaxy, f'{int(coili.N)}', fontsize=8,ha='center')
bx5.text(coil_loci, -textmaxy-4, f'{Coil_Odi:.1f}', fontsize=8,ha='center')
bx5.text(coil_loci, -textmaxy-8, f'{coili.pwi*1000:.1f}', fontsize=8,ha='center')
# 初始化文本对象,用于显示slug_text
slug_text = bx5.text(0.25, textmaxy+4, '')
# 显示电流
yss_amim = [bx5.text(0.25, textmaxy-4, '', fontsize=8,ha='center') for x in cnumnp]
#
# 动子运动动画
slug_anim, = bx5.plot([], [], lw=2)
# BField动画
BField_anim, = bx5.plot([], [], lw=2)
t__r=interp1d(t, r_mm*1e-3, kind='linear', bounds_error=False, fill_value="extrapolate")
t__v=interp1d(t, v , kind='linear', bounds_error=False, fill_value="extrapolate")
t__yssi=[interp1d(t, yss[i] , kind='linear', bounds_error=False, fill_value="extrapolate") for i in cnumnp ]
r__t=interp1d(r_mm*1e-3,t , kind='linear', bounds_error=False, fill_value="extrapolate")
t__U=interp1d(t, U , kind='linear', bounds_error=False, fill_value="extrapolate")
# 动画更新函数,每帧调用一次
def update(frame):
slug_t= frame*1e-4
global slug_r_glaobal
if slug_r_glaobal !=-1000:
slug_t = r__t(slug_r_glaobal)
slug_loc= t__r(slug_t)
slug_v=t__v(slug_t)
slug_U=t__U(slug_t)
#######画行波
BField=[]
coilsneed = [coili for coili in coils if t__yssi[coili.i](slug_t)>1 ]
for coili in coilsneed:
bFieldi = []
for slug_ri in r_mm:
bFieldi.append( coili.BFieldCoil(slug_ri*1e-3 -coili.r, t__yssi[coili.i](slug_t) ) if abs(slug_ri*1e-3 -coili.r) < 2*Mode.preset["slug_length"] else 0 )
BField.append(bFieldi)
BField_sum = [5*sum(col)-1000*Mode.preset["slug_R"]/2 for col in zip(*BField)] # 使用zip函数和列表推导式按“列”相加
BField_B = [sum(col) for col in zip(*BField)] # 使用zip函数和列表推导式按“列”相加 (10,12,14,16)
try:
BField_range = BField_sum
if(len(r_mm)==len(BField_range)):
BField_anim.set_data(r_mm,BField_range)
slug_text.set_text(f'电压={slug_U:.2f} |速度= {slug_v:.2f}m/s |位置= {slug_loc*1e+3:.2f}mm |时间= {slug_t*1e+6:.0f}us ,外部磁场峰值:{max(BField_B):.2f}T')
except:
pass
#print(slug_loc)
#动子运动
xxx=[1000*(slug_loc-0.5*Mode.preset["slug_length"]) ,1000*(slug_loc-0.5*Mode.preset["slug_length"]) ,1000*(slug_loc+0.5*Mode.preset["slug_length"]) ,1000*(slug_loc+0.5*Mode.preset["slug_length"]) ,1000*(slug_loc-0.5*Mode.preset["slug_length"])]
yyy=[-1000*0.5*Mode.preset["slug_R"] ,1000*0.5*Mode.preset["slug_R"] ,1000*0.5*Mode.preset["slug_R"] ,-1000*0.5*Mode.preset["slug_R"] ,-1000*0.5*Mode.preset["slug_R"]]
slug_anim.set_data(xxx, yyy)
#
#对电流图做标记
for texti,coili,cnumi in zip(yss_amim,coil_loc,cnumnp):
texti.set_x(coili)
texti.set_text(str(int(t__yssi[cnumi](slug_t) ) ) ) #, va='bottom'
aa=[slug_anim,slug_text,BField_anim]
return aa + yss_amim
# 创建动画
ani = FuncAnimation(fig, update, frames=np.arange(0, int(t[-1]*1e+4)+1 ),
blit=True)
if combo_showplt.get() == '仅显示位移图' : #显示位移图
plt.show()
elif combo_showplt.get() == '同时显示位移与时间图' : #显示时间图
plt.show(block=False)
fig2 = plt.figure() # 创建一个新的figure对象
cx1 = fig2.add_subplot(511)
cx1.set_ylabel("线圈电流 / A")
cx2 = fig2.add_subplot(512, sharex = cx1)
cx2.set_ylabel("力 / N")
cx3 = fig2.add_subplot(513, sharex = cx1)
cx3.set_ylabel("电容电压 / V")
cx4 = fig2.add_subplot(514, sharex = cx1)
cx4.set_ylabel("动子速度 / m/s")
cx4.set_xlabel(f"时间 / us ")
t_us=np.array(t)*1e+6
for i in range(Mode.preset["coil_number"]):
cx1.plot(t_us,yss[i])
coil_loc=np.array( [ round(coili.r*1000,2) for coili in coils] )
coil_num = [i for i in range(Mode.preset["coil_number"])]
###########
cx2.plot(t_us[1:],((v[1:]-v[:-1])/ (t[1:]-t[:-1]) )*Mode.preset["m"]) #f=ma ,计算力的第二种方法,a=v*dv/dr,a=dv/dt
cx3.plot(t_us,U)
cx4.plot(t_us,v, color='red')
plt.show()
#--------------------------------gui--------------------------------
def getmodei():
global modecsv
global combo_selectfile
modecsv=script_directory+'\\' +str(combo_selectfile.get())
print("mode.csv路径: "+modecsv)
Modefile=pd.read_csv(modecsv, index_col=False, encoding='GBK')
modeidata = np.array( Modefile.loc[:, '匝径start'].values) #
# 初始化一个变量来跟踪当前非nan序列的长度
current_length = 0
input_lines=[]
input_line_start=0
# 遍历数据列表
for i in range(len(modeidata)):
if isinstance(modeidata[i], str) or not np.isnan(modeidata[i]): # 检查当前值是否不是nan
current_length += 1 # 增加当前序列的长度
else:
if current_length > 0: # 如果当前序列长度大于0,则打印或处理它
input_lines.append([input_line_start+3,input_line_start+3+current_length-1])
current_length = 0 # 重置当前序列的长度
input_line_start =i
#追加最后一组数据
input_lines.append([input_line_start+3,input_line_start+3+current_length-1])
input_lines_dict=[ str([Modefile.loc[line[0]-2,'唯一id'] ,line[0],line[1] ]) for line in input_lines]
# 初始化数据
data = input_lines_dict#[
return data
if __name__ == '__main__':
multiprocessing.freeze_support()
print(f"版本号为:{__version__}\n")
def reset_combobox():
global combo_modei
# 销毁旧的选项框
combo_modei.destroy()
# 创建新的选项框,并添加新的选项
combo_modei = ttk.Combobox(root, width=20)
data=getmodei()
combo_modei['values'] = (data)
combo_modei.current(0)
combo_modei.pack()
def startmymain():
global combo_modei
getmodei()
modidata = eval(combo_modei.get()) #[int(num) for num in combo_modei.get().split()]
global Mode
Mode=CoilMode(modidata)
if(Mode.combo_scanning_list == [[],[]]):
try :
subprocess.run(f"taskkill /F /IM wps.exe", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except Exception as e:
print(f"An error occurred while trying to kill the process: {e}")
Mode.lin_preset_To_preset()
not_scanning_main(Mode)
else:
scanning_main(Mode)
try :
root = tk.Tk()
# 开始模拟按钮
start_button = tk.Button(root, text='开始模拟', command=startmymain)
start_button.pack()
reset_button = tk.Button(root, text='刷新选项', command=reset_combobox)
reset_button.pack()
global combo_showplt
combo_showplt = ttk.Combobox(root, width=20 )
combo_showplt['values'] = (['仅显示位移图','同时显示位移与时间图'])
combo_showplt.current(0)
combo_showplt.pack()
global combo_step_select
combo_step_select = ttk.Combobox(root, width=20 )
combo_step_select['values'] = (['使用默认后续微元步进','0.05','0.1','0.2','0.5','1'])
combo_step_select.current(0)
combo_step_select.pack()
global combo_Mcaulate_select
combo_Mcaulate_select = ttk.Combobox(root, width=20 )
combo_Mcaulate_select['values'] = (['粗略计算互感','精细计算互感','不计算互感'])
combo_Mcaulate_select.current(0)
combo_Mcaulate_select.pack()
global combo_extra_information_select
combo_extra_information_select = ttk.Combobox(root, width=20 )
combo_extra_information_select['values'] = (['显示额外信息','不显示额外信息'])
combo_extra_information_select.current(0)
combo_extra_information_select.pack()
global combo_paoguan_select
combo_paoguan_select = ttk.Combobox(root, width=20 )
combo_paoguan_select['values'] = (['参数扫描时不进行炮管长度限制','400'])
combo_paoguan_select.current(0)
combo_paoguan_select.pack()
entries = os.listdir(script_directory)
files = [entry for entry in entries if entry.endswith('.csv')]
global combo_selectfile
combo_selectfile = ttk.Combobox(root, width=20 )
combo_selectfile['values'] = (files)
combo_selectfile.current(0)
combo_selectfile.pack()
data=getmodei()
global combo_modei
# 初始选项框
combo_modei = ttk.Combobox(root, width=20 )
combo_modei['values'] = (data)
combo_modei.current(0)
combo_modei.pack()
global slug_r_glaobal
slug_r_glaobal=-1000
root.mainloop()
except Exception as e:
print(f"\n {e}\n")
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。