Reputation: 61
I have my button and function in GUI as shown below. RUN function calculates X and Y coordinates along with color values and then plots them using matplotlib. Since the calculations and plotting takes time, Tkinter freezes until it's completed. I've seen people using threading but I couldn't really adapt it to my own code. How can I stop Tkinter from freezing?
RUNButton = Button(RUNFrame, text="RUN", width = 10, style='RUN.TButton', command = lambda: RUN(voidORinc.get()))
RUNButton.grid(row=0,column=0,padx=10,ipady=15,pady=5,columnspan=2)
def RUN(inclusion):
global deformationType
global NL
global EL
global ENL
global cEntry
global dEntry
global dropElementType
global axstress_xx
global axstress_xy
global axstress_yx
global axstress_yy
global axstrain_xx
global axstrain_xy
global axstrain_yx
global axstrain_yy
global axdisp_x
global axdisp_y
global analysisType
(ENL,DOFs,DOCs) = assign_BCs(NL,deformationType.get())
K = assemble_stiffness( ENL ,EL , NL , int(cEntry.get()) , int(dEntry.get()) , inclusion )
Fp = assemble_forces(ENL,NL)
Up = assemble_displacements(ENL,NL)
K_reduced = K[0:DOFs, 0:DOFs] #K_UU
K_UP = K[0:DOFs, DOFs:DOCs+DOFs]
K_PU = K_PU= K[DOFs:DOCs+DOFs, 0:DOFs]
K_PP= K[DOFs:DOCs+DOFs, DOFs:DOCs+DOFs]
F = Fp - (K_UP @ Up)
Uu = np.linalg.solve( K_reduced, F)
Fu = (K_PU @ Uu) + (K_PP @ Up)
ENL = update_nodes(ENL,Uu,Fu,NL)
(stress_xx,stress_xy,stress_yx,stress_yy,strain_xx,strain_xy,strain_yx,strain_yy,disp_x,disp_y,X,Y) = post_process(NL, EL, ENL, int(cEntry.get()), int(dEntry.get()), inclusion)
option = analysisType.get()
"""
POLYGONAL PLOTS
"""
axstress_xx.cla()
axstress_xy.cla()
axstress_yx.cla()
axstress_yy.cla()
axstrain_xx.cla()
axstrain_xy.cla()
axstrain_yx.cla()
axstrain_yy.cla()
axdisp_x.cla()
axdisp_y.cla()
if option == 'Polygonal':
stress_xxNormalized = (np.mean(stress_xx, axis=0) - np.mean(stress_xx, axis=0).min()) / (np.mean(stress_xx, axis=0).max() - np.mean(stress_xx, axis=0).min())
stress_xyNormalized = (np.mean(stress_xy, axis=0) - np.mean(stress_xy, axis=0).min()) / (np.mean(stress_xy, axis=0).max() - np.mean(stress_xy, axis=0).min())
stress_yxNormalized = (np.mean(stress_yx, axis=0) - np.mean(stress_yx, axis=0).min()) / (np.mean(stress_yx, axis=0).max() - np.mean(stress_yx, axis=0).min())
stress_yyNormalized = (np.mean(stress_yy, axis=0) - np.mean(stress_yy, axis=0).min()) / (np.mean(stress_yy, axis=0).max() - np.mean(stress_yy, axis=0).min())
strain_xxNormalized = (np.mean(strain_xx, axis=0) - np.mean(strain_xx, axis=0).min()) / (np.mean(strain_xx, axis=0).max() - np.mean(strain_xx, axis=0).min())
strain_xyNormalized = (np.mean(strain_xy, axis=0) - np.mean(strain_xy, axis=0).min()) / (np.mean(strain_xy, axis=0).max() - np.mean(strain_xy, axis=0).min())
strain_yxNormalized = (np.mean(strain_yx, axis=0) - np.mean(strain_yx, axis=0).min()) / (np.mean(strain_yx, axis=0).max() - np.mean(strain_yx, axis=0).min())
strain_yyNormalized = (np.mean(strain_yy, axis=0) - np.mean(strain_yy, axis=0).min()) / (np.mean(strain_yy, axis=0).max() - np.mean(strain_yy, axis=0).min())
disp_xNormalized = (np.mean(abs(disp_x), axis=0) - np.mean(abs(disp_x), axis=0).min()) / (np.mean(abs(disp_x), axis=0).max() - np.mean(abs(disp_x), axis=0).min())
disp_yNormalized = (np.mean(abs(disp_y), axis=0) - np.mean(abs(disp_y), axis=0).min()) / (np.mean(abs(disp_y), axis=0).max() - np.mean(abs(disp_y), axis=0).min())
patches = []
for i in range(len(stress_xxNormalized)):
verts = np.hstack([np.array([X[:,i]]).T,np.array([Y[:,i]]).T])
polygon = Polygon(verts)
patches.append(polygon)
polygon.set_edgecolor('black')
cmap = plt.get_cmap('jet')
colors1 = cmap(stress_xxNormalized)
colors2 = cmap(stress_xyNormalized)
colors3 = cmap(stress_yxNormalized)
colors4 = cmap(stress_yyNormalized)
colors5 = cmap(strain_xxNormalized)
colors6 = cmap(strain_xyNormalized)
colors7 = cmap(strain_yxNormalized)
colors8 = cmap(strain_yyNormalized)
colors9 = cmap(disp_xNormalized)
colors10 = cmap(disp_yNormalized)
collection1 = PatchCollection(patches)
collection2 = PatchCollection(patches)
collection3 = PatchCollection(patches)
collection4 = PatchCollection(patches)
collection5 = PatchCollection(patches)
collection6 = PatchCollection(patches)
collection7 = PatchCollection(patches)
collection8 = PatchCollection(patches)
collection9 = PatchCollection(patches)
collection10 = PatchCollection(patches)
axstress_xx.add_collection(collection1)
axstress_xy.add_collection(collection2)
axstress_yx.add_collection(collection3)
axstress_yy.add_collection(collection4)
axstrain_xx.add_collection(collection5)
axstrain_xy.add_collection(collection6)
axstrain_yx.add_collection(collection7)
axstrain_yy.add_collection(collection8)
axdisp_x.add_collection(collection9)
axdisp_y.add_collection(collection10)
collection1.set_facecolor(colors1)
collection2.set_facecolor(colors2)
collection3.set_facecolor(colors3)
collection4.set_facecolor(colors4)
collection5.set_facecolor(colors5)
collection6.set_facecolor(colors6)
collection7.set_facecolor(colors7)
collection8.set_facecolor(colors8)
collection9.set_facecolor(colors9)
collection10.set_facecolor(colors10)
collection1.set_edgecolor('black')
collection2.set_edgecolor('black')
collection3.set_edgecolor('black')
collection4.set_edgecolor('black')
collection5.set_edgecolor('black')
collection6.set_edgecolor('black')
collection7.set_edgecolor('black')
collection8.set_edgecolor('black')
collection9.set_edgecolor('black')
collection10.set_edgecolor('black')
axstress_xx.autoscale_view()
axstress_xy.autoscale_view()
axstress_yx.autoscale_view()
axstress_yy.autoscale_view()
axstrain_xx.autoscale_view()
axstrain_xy.autoscale_view()
axstrain_yx.autoscale_view()
axstrain_yy.autoscale_view()
axdisp_x.autoscale_view()
axdisp_y.autoscale_view()
"""
TRICONTOURF PLOTS
"""
if option == 'Contour':
stress_xxNormalized = (stress_xx - stress_xx.min()) / (stress_xx.max() - stress_xx.min())
stress_xyNormalized = (stress_xy - stress_xy.min()) / (stress_xy.max() - stress_xy.min())
stress_yxNormalized = (stress_yx - stress_yx.min()) / (stress_yx.max() - stress_yx.min())
stress_yyNormalized = (stress_yy - stress_yy.min()) / (stress_yy.max() - stress_yy.min())
strain_xxNormalized = (strain_xx - strain_xx.min()) / (strain_xx.max() - strain_xx.min())
strain_xyNormalized = (strain_xy - strain_xy.min()) / (strain_xy.max() - strain_xy.min())
strain_yxNormalized = (strain_yx - strain_yx.min()) / (strain_yx.max() - strain_yx.min())
strain_yyNormalized = (strain_yy - strain_yy.min()) / (strain_yy.max() - strain_yy.min())
disp_xNormalized = (disp_x - disp_x.min()) / (disp_x.max() - disp_x.min())
disp_yNormalized = (disp_y - disp_y.min()) / (disp_y.max() - disp_y.min())
for i in range(np.size(X,1)):
x = X[:,i]
y = Y[:,i]
c = stress_xxNormalized[:,i]
cmap = truncate_colormap(plt.get_cmap('jet'), c.min(), c.max())
axstress_xx.tricontourf(x,y,c ,cmap = cmap,levels=1)
for i in range(np.size(X,1)):
x = X[:,i]
y = Y[:,i]
c = stress_xyNormalized[:,i]
cmap = truncate_colormap(plt.get_cmap('jet'), c.min(), c.max())
axstress_xy.tricontourf(x,y,c, cmap = cmap,levels=1)
for i in range(np.size(X,1)):
x = X[:,i]
y = Y[:,i]
c = stress_yxNormalized[:,i]
cmap = truncate_colormap(plt.get_cmap('jet'), c.min(), c.max())
axstress_yx.tricontourf(x,y,c, cmap = cmap,levels=1)
for i in range(np.size(X,1)):
x = X[:,i]
y = Y[:,i]
c = stress_yyNormalized[:,i]
cmap = truncate_colormap(plt.get_cmap('jet'), c.min(), c.max())
axstress_yy.tricontourf(x,y,c, cmap = cmap,levels=1)
for i in range(np.size(X,1)):
x = X[:,i]
y = Y[:,i]
c = strain_xxNormalized[:,i]
cmap = truncate_colormap(plt.get_cmap('jet'), c.min(), c.max())
axstrain_xx.tricontourf(x,y,c, cmap = cmap,levels=1)
for i in range(np.size(X,1)):
x = X[:,i]
y = Y[:,i]
c = strain_xyNormalized[:,i]
cmap = truncate_colormap(plt.get_cmap('jet'), c.min(), c.max())
axstrain_xy.tricontourf(x,y,c, cmap = cmap,levels=1)
for i in range(np.size(X,1)):
x = X[:,i]
y = Y[:,i]
c = strain_yxNormalized[:,i]
cmap = truncate_colormap(plt.get_cmap('jet'), c.min(), c.max())
axstrain_yx.tricontourf(x,y,c, cmap = cmap,levels=1)
for i in range(np.size(X,1)):
x = X[:,i]
y = Y[:,i]
c = strain_yyNormalized[:,i]
cmap = truncate_colormap(plt.get_cmap('jet'), c.min(), c.max())
axstrain_yy.tricontourf(x,y,c, cmap = cmap,levels=1)
for i in range(np.size(X,1)):
x = X[:,i]
y = Y[:,i]
c = disp_xNormalized[:,i]
cmap = truncate_colormap(plt.get_cmap('jet'), c.min(), c.max())
axdisp_x.tricontourf(x,y,c, cmap = cmap,levels=1)
for i in range(np.size(X,1)):
x = X[:,i]
y = Y[:,i]
c = disp_yNormalized[:,i]
cmap = truncate_colormap(plt.get_cmap('jet'), c.min(), c.max())
axdisp_y.tricontourf(x,y,c, cmap = cmap,levels=1)
canvasAnalysis.draw()
Edit: This is what I tried so far:
def RUN(inclusion):
... function content above
RUNFrame = LabelFrame(processFrame)
RUNFrame.grid(row=1,column=2,padx=10)
RUNButton = Button(RUNFrame, text="RUN", width = 10, style='RUN.TButton', command = threading.Thread(target=RUN, args=(voidORinc.get(), )))
RUNButton.grid(row=0,column=0,padx=10,ipady=15,pady=5,columnspan=2)
I get the error "name RUNFrame is not defined"
Upvotes: 0
Views: 873
Reputation: 142651
Button
should run function which creates thread
and start it.
If in RUN
you use some values from widgets then you could send them as arguments becaues most GUIs don't like to use widgets in separated threads.
Button(..., command=run_calculations)
def run_calculations():
t = threading.Thread(taget=RUN, args=(voidORinc.get(), cEntry.get()) , int(dEntry.get(), ...))
t.start()
Eventually in RUN
you should use periodically root.update()
(where root
is main window) to force tkinter
to get key/mouse events from system, send them to widgets, and redraw widgets. And this way it will not freeze. And this doesn't need thread
def RUN(inclusion):
# ... some part of code ...
root.update()
# ... some part of code ...
root.update()
# ... some part of code ...
root.update()
Upvotes: 2