Tkinter GUI 无响应
Tkinter GUI unresponsive
我正在尝试制作一个 GUI 来使用广泛接受的方法(暗示该方法是无缝的)来解决工程设计问题。
当 运行 独立时,此方法的代码需要 0.537909984588623 秒(不是在 tkinter 中,而是在正常代码中),而且它不太复杂或纠结。当我尝试使用 tkinter 修改此代码以适应 GUI 时,在我输入所有输入和 select 按钮后它变得无响应,即使程序在后台保持 运行ning。
此外,当我强行关闭 GUI window 时,jupyter 内核就死了。
下面是我的代码的简要概述:
from tkinter import *
from scipy.optimize import fsolve
import matplotlib
import numpy as np
import threading
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
matplotlib.use('TkAgg')
import math
class MyWindow():
def __init__(self, win):
self.lbl1=Label(win, text='Alpha')
self.lbl2=Label(win, text='xd')
self.lbl3=Label(win, text='xw')
self.lbl4=Label(win, text='xf')
self.lbl5=Label(win, text='q')
self.lbl6=Label(win, text='Reflux Factor')
self.lbl7=Label(win, text='Tray Efficiency')
self.lbl8=Label(win, text='Total Number of Stages')
self.lbl9=Label(win, text='Feed Stage')
self.t1=Entry(bd=3)
self.t2=Entry(bd=3)
self.t3=Entry(bd=3)
self.t4=Entry(bd=3)
self.t5=Entry(bd=8)
self.t6=Entry(bd=8)
self.t7=Entry(bd=8)
self.t8=Entry(bd=8)
self.t9=Entry(bd=8)
self.btn1=Button(win, text='Total Number of Stages ', command=self.stagesN)
self.lbl1.place(x=100, y=80)
self.t1.place(x=300, y=80)
self.lbl2.place(x=100, y=130)
self.t2.place(x=300, y=130)
self.lbl3.place(x=100, y=180)
self.t3.place(x=300, y=180)
self.lbl4.place(x=100, y=230)
self.t4.place(x=300, y=230)
self.lbl5.place(x=100, y=280)
self.t5.place(x=300, y=280)
self.lbl6.place(x=100, y=330)
self.t6.place(x=300, y=330)
self.lbl7.place(x=100, y=380)
self.t7.place(x=300, y=380)
self.lbl8.place(x=800, y=130)
self.t8.place(x=790, y=170)
self.lbl9.place(x=800, y=210)
self.t9.place(x=790, y=260)
self.btn1.place(x= 500, y= 75)
def originalEq(self,xa,relative_volatility):
ya=(relative_volatility*xa)/(1+(relative_volatility-1)*xa)
return ya
def equilibriumReal(self,xa,relative_volatility,nm):
ya=(relative_volatility*xa)/(1+(relative_volatility-1)*xa)
ya=((ya-xa)*nm)+xa
return ya
def equilibriumReal2(self,ya,relative_volatility,nm):
a=((relative_volatility*nm)-nm-relative_volatility+1)
b=((ya*relative_volatility)-ya+nm-1-(relative_volatility*nm))
c=ya
xa=(-b-np.sqrt((b**2)-(4*a*c)))/(2*a)
return xa
def stepping_ESOL(self,x1,y1,relative_volatility,R,xd,nm):
x2=self.equilibriumReal2(y1,relative_volatility,nm)
y2=(((R*x2)/(R+1))+(xd/(R+1)))
return x1,x2,y1,y2
def stepping_SSOL(self,x1,y1,relative_volatility,\
ESOL_q_x,ESOL_q_y,xb,nm):
x2=self.equilibriumReal2(y1,relative_volatility,nm)
m=((xb-ESOL_q_y)/(xb-ESOL_q_x))
c=ESOL_q_y-(m*ESOL_q_x)
y2=(m*x2)+c
return x1,x2,y1,y2
def stagesN(self):
relative_volatility=float(self.t1.get())
nm=float(self.t7.get())
xd=float(self.t2.get())
xb=float(self.t3.get())
xf=float(self.t4.get())
q=float(self.t5.get())
R_factor=float(self.t6.get())
xa=np.linspace(0,1,100)
ya_og=self.originalEq(xa[:],relative_volatility)
ya_eq=self.equilibriumReal(xa[:],relative_volatility,nm)
x_line=xa[:]
y_line=xa[:]
al=relative_volatility
a=((al*q)/(q-1))-al+(al*nm)-(q/(q-1))+1-nm
b=(q/(q-1))-1+nm+((al*xf)/(1-q))-(xf/(1-q))-(al*nm)
c=xf/(1-q)
if q>1:
q_eqX=(-b+np.sqrt((b**2)-(4*a*c)))/(2*a)
else:
q_eqX=(-b-np.sqrt((b**2)-(4*a*c)))/(2*a)
q_eqy=self.equilibriumReal(q_eqX,relative_volatility,nm)
theta_min=xd*(1-((xd-q_eqy)/(xd-q_eqX)))
R_min=(xd/theta_min)-1
R=R_factor*R_min
theta=(xd/(R+1))
ESOL_q_x=((theta-(xf/(1-q)))/((q/(q-1))-((xd-theta)/xd)))
ESOL_q_y=(ESOL_q_x*((xd-theta)/xd))+theta
x1,x2,y1,y2=self.stepping_ESOL(xd,xd,relative_volatility,R,xd,nm)
step_count=1
while x2>ESOL_q_x:
x1,x2,y1,y2=self.stepping_ESOL(x2,y2,relative_volatility,R,xd,nm)
step_count+=1
feed_stage=step_count
x1,x2,y1,y2=self.stepping_SSOL(x1,y1,relative_volatility\
,ESOL_q_x,ESOL_q_y,xb,nm)
step_count+=1
while x2>xb:
x1,x2,y1,y2=self.stepping_SSOL(x2,y2,relative_volatility\
,ESOL_q_x,ESOL_q_y,xb,nm)
step_count+=1
xb_actual=x2
stagesN=step_count-1
self.t8.insert(END, str(stagesN))
return
window=Tk()
mywin=MyWindow(window)
window.title('DColumn')
window.geometry("1500x1500")
window.mainloop()
我在其他文章中读到,使用多线程可以降低主循环的负载并防止冻结。但就像我说的,代码不是很复杂。还是因为 everythings 运行ning on the mainloop?或者有什么比满足眼睛更多的东西?多线程是克服这一点的唯一方法吗?
代码并不像你说的那么简单,因为使用了 matpotlib 和其他模块,它可能没有响应。
如果您长时间离开 Tkinter GUI 运行,它会导致错误并且没有响应,
以下内容可能会有所帮助:
- 将代码拆分为 类 和适当的结构
- 同时防止许多 while 循环和 def 函数运行
- 不要同时从另一个函数调用多个函数
- 防止来回循环
但没有解决整个无响应问题
tkinter 是一个非常基本的 GUI,用于制作小型 programmes/games。即使您的代码没有那么复杂,最好使用替代的强大 GUI
我正在尝试制作一个 GUI 来使用广泛接受的方法(暗示该方法是无缝的)来解决工程设计问题。
当 运行 独立时,此方法的代码需要 0.537909984588623 秒(不是在 tkinter 中,而是在正常代码中),而且它不太复杂或纠结。当我尝试使用 tkinter 修改此代码以适应 GUI 时,在我输入所有输入和 select 按钮后它变得无响应,即使程序在后台保持 运行ning。
此外,当我强行关闭 GUI window 时,jupyter 内核就死了。
下面是我的代码的简要概述:
from tkinter import *
from scipy.optimize import fsolve
import matplotlib
import numpy as np
import threading
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
matplotlib.use('TkAgg')
import math
class MyWindow():
def __init__(self, win):
self.lbl1=Label(win, text='Alpha')
self.lbl2=Label(win, text='xd')
self.lbl3=Label(win, text='xw')
self.lbl4=Label(win, text='xf')
self.lbl5=Label(win, text='q')
self.lbl6=Label(win, text='Reflux Factor')
self.lbl7=Label(win, text='Tray Efficiency')
self.lbl8=Label(win, text='Total Number of Stages')
self.lbl9=Label(win, text='Feed Stage')
self.t1=Entry(bd=3)
self.t2=Entry(bd=3)
self.t3=Entry(bd=3)
self.t4=Entry(bd=3)
self.t5=Entry(bd=8)
self.t6=Entry(bd=8)
self.t7=Entry(bd=8)
self.t8=Entry(bd=8)
self.t9=Entry(bd=8)
self.btn1=Button(win, text='Total Number of Stages ', command=self.stagesN)
self.lbl1.place(x=100, y=80)
self.t1.place(x=300, y=80)
self.lbl2.place(x=100, y=130)
self.t2.place(x=300, y=130)
self.lbl3.place(x=100, y=180)
self.t3.place(x=300, y=180)
self.lbl4.place(x=100, y=230)
self.t4.place(x=300, y=230)
self.lbl5.place(x=100, y=280)
self.t5.place(x=300, y=280)
self.lbl6.place(x=100, y=330)
self.t6.place(x=300, y=330)
self.lbl7.place(x=100, y=380)
self.t7.place(x=300, y=380)
self.lbl8.place(x=800, y=130)
self.t8.place(x=790, y=170)
self.lbl9.place(x=800, y=210)
self.t9.place(x=790, y=260)
self.btn1.place(x= 500, y= 75)
def originalEq(self,xa,relative_volatility):
ya=(relative_volatility*xa)/(1+(relative_volatility-1)*xa)
return ya
def equilibriumReal(self,xa,relative_volatility,nm):
ya=(relative_volatility*xa)/(1+(relative_volatility-1)*xa)
ya=((ya-xa)*nm)+xa
return ya
def equilibriumReal2(self,ya,relative_volatility,nm):
a=((relative_volatility*nm)-nm-relative_volatility+1)
b=((ya*relative_volatility)-ya+nm-1-(relative_volatility*nm))
c=ya
xa=(-b-np.sqrt((b**2)-(4*a*c)))/(2*a)
return xa
def stepping_ESOL(self,x1,y1,relative_volatility,R,xd,nm):
x2=self.equilibriumReal2(y1,relative_volatility,nm)
y2=(((R*x2)/(R+1))+(xd/(R+1)))
return x1,x2,y1,y2
def stepping_SSOL(self,x1,y1,relative_volatility,\
ESOL_q_x,ESOL_q_y,xb,nm):
x2=self.equilibriumReal2(y1,relative_volatility,nm)
m=((xb-ESOL_q_y)/(xb-ESOL_q_x))
c=ESOL_q_y-(m*ESOL_q_x)
y2=(m*x2)+c
return x1,x2,y1,y2
def stagesN(self):
relative_volatility=float(self.t1.get())
nm=float(self.t7.get())
xd=float(self.t2.get())
xb=float(self.t3.get())
xf=float(self.t4.get())
q=float(self.t5.get())
R_factor=float(self.t6.get())
xa=np.linspace(0,1,100)
ya_og=self.originalEq(xa[:],relative_volatility)
ya_eq=self.equilibriumReal(xa[:],relative_volatility,nm)
x_line=xa[:]
y_line=xa[:]
al=relative_volatility
a=((al*q)/(q-1))-al+(al*nm)-(q/(q-1))+1-nm
b=(q/(q-1))-1+nm+((al*xf)/(1-q))-(xf/(1-q))-(al*nm)
c=xf/(1-q)
if q>1:
q_eqX=(-b+np.sqrt((b**2)-(4*a*c)))/(2*a)
else:
q_eqX=(-b-np.sqrt((b**2)-(4*a*c)))/(2*a)
q_eqy=self.equilibriumReal(q_eqX,relative_volatility,nm)
theta_min=xd*(1-((xd-q_eqy)/(xd-q_eqX)))
R_min=(xd/theta_min)-1
R=R_factor*R_min
theta=(xd/(R+1))
ESOL_q_x=((theta-(xf/(1-q)))/((q/(q-1))-((xd-theta)/xd)))
ESOL_q_y=(ESOL_q_x*((xd-theta)/xd))+theta
x1,x2,y1,y2=self.stepping_ESOL(xd,xd,relative_volatility,R,xd,nm)
step_count=1
while x2>ESOL_q_x:
x1,x2,y1,y2=self.stepping_ESOL(x2,y2,relative_volatility,R,xd,nm)
step_count+=1
feed_stage=step_count
x1,x2,y1,y2=self.stepping_SSOL(x1,y1,relative_volatility\
,ESOL_q_x,ESOL_q_y,xb,nm)
step_count+=1
while x2>xb:
x1,x2,y1,y2=self.stepping_SSOL(x2,y2,relative_volatility\
,ESOL_q_x,ESOL_q_y,xb,nm)
step_count+=1
xb_actual=x2
stagesN=step_count-1
self.t8.insert(END, str(stagesN))
return
window=Tk()
mywin=MyWindow(window)
window.title('DColumn')
window.geometry("1500x1500")
window.mainloop()
我在其他文章中读到,使用多线程可以降低主循环的负载并防止冻结。但就像我说的,代码不是很复杂。还是因为 everythings 运行ning on the mainloop?或者有什么比满足眼睛更多的东西?多线程是克服这一点的唯一方法吗?
代码并不像你说的那么简单,因为使用了 matpotlib 和其他模块,它可能没有响应。
如果您长时间离开 Tkinter GUI 运行,它会导致错误并且没有响应,
以下内容可能会有所帮助:
- 将代码拆分为 类 和适当的结构
- 同时防止许多 while 循环和 def 函数运行
- 不要同时从另一个函数调用多个函数
- 防止来回循环
但没有解决整个无响应问题
tkinter 是一个非常基本的 GUI,用于制作小型 programmes/games。即使您的代码没有那么复杂,最好使用替代的强大 GUI