问题描述
我需要在线程计时器的每次迭代中更新 TKagg 画布图。该图显示在计时器的第一次迭代中,然后程序暂停并输出 - '进程完成,退出代码 -1073741819 (0xC0000005)'
几天来,我一直在努力让这段代码正常工作。任何帮助,将不胜感激。代码按原样运行,应该输出相同的退出代码。我不知道如何附加我的测试矩阵,但它只是一个 401x401 的 numpy 数组,包含 0.0-0.05 之间的值
import threading
from tkinter import *
from tkinter import ttk
import tkinter as tk
import numpy as np
import matplotlib
from matplotlib.backends.backend_tkagg import figureCanvasTkAgg
from matplotlib.figure import figure
matplotlib.use('Agg')
from matplotlib import cm,colors
import os
import os.path
class APP(tk.Tk):
update_interval = 0.2
dwell_time = np.array([20.,20.,20.])
current_count = 0
colormap = 'jet'
window_height = 480
window_width = 720
num_columns = 20
num_rows = 20
canvas_width = window_width / num_columns * 13
canvas_height = window_height / num_rows * 16
def __init__(self,*args,**kwargs):
tk.Tk.__init__(self,**kwargs)
# create a container
container = tk.Frame(self)
container.pack(side="top",fill="both",expand=False)
container.grid_rowconfigure(0,weight=1)
container.grid_columnconfigure(0,weight=1)
# initialize an empty array of frames
self.frames = {}
# iterate through the tuple of page frames - basically creates/configures an empty frame for each page
for F in (Page1,Page2):
frame = F(container,self)
self.frames[F] = frame
frame.grid(row=0,column=0,sticky="NSEW")
frame.grid_rowconfigure(0,weight=1) # fills the whole window
frame.grid_columnconfigure(0,weight=1) # fills the whole window
self.show_frame(Page1)
def show_frame(self,cont):
frame = self.frames[cont]
frame.tkraise()
def resource_path(relative_path):
return os.path.join(os.path.dirname(os.path.abspath(__file__)),relative_path)
filename = "22222222_20210203083122.csv"
filepath = resource_path('PDT_Patient_Treatment_Maps/' + filename)
dose_map = np.load(resource_path('test.npy'))
print(dose_map)
class Page1(tk.Frame):
f = figure()
update_interval = 0.2
dwell_time = np.array([20.,20.])
current_count = 0
colormap = 'jet'
window_height = 480
window_width = 720
num_columns = 20
num_rows = 20
canvas_width = window_width / num_columns * 13
canvas_height = window_height / num_rows * 16
plt = f.add_subplot(111)
def start_treatment(self):
counts_per_each_diffuser = (APP.dwell_time / APP.update_interval).astype(int)
self.cumulative_count = counts_per_each_diffuser.cumsum()
self.total_count = self.cumulative_count[-1]
self.max_count = counts_per_each_diffuser.max()
self.current_map = np.zeros(APP.dose_map.shape) # initialize detection map
self.timer_update()
def timer_update(self):
"""update detector map and progress bar"""
timer = threading.Timer(APP.update_interval,self.timer_update)
timer.start()
if APP.current_count >= self.total_count:
timer.cancel()
APP.current_count = 0
else:
self.update_det_map()
self.current_count += 1
current_percentage = self.current_count / self.total_count
current_percentage = current_percentage if current_percentage <= 1 else 1
self.progress['value'] = round(current_percentage,3) * 100
self.style.configure('text.Horizontal.TProgressbar',text='{:.1%}'.format(current_percentage))
def update_det_map(self):
self.show_det_map(self.current_map,self.det_canvas,self.plt)
def show_det_map(self,map_data,canvas,ax):
"""convert 2d map data into PhotoImage RGB data and draw it on detector canvas"""
self.gray2rgb = cm.get_cmap(self.colormap)
img = (np.delete(self.gray2rgb(map_data),3,2) * 255).astype(np.uint8)
ax.clear()
ax.imshow(img,cmap=self.gray2rgb)
canvas.draw()
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
# initializes grid to have evenly weighted rows and columns for the page
# self.dose_map = dose_map
cols = 0
while cols < 20:
self.grid_columnconfigure(cols,weight=1)
self.grid_rowconfigure(cols,weight=1)
cols += 1
self.det_canvas = figureCanvasTkAgg(self.f,self)
self.det_canvas.draw()
self.det_canvas.get_tk_widget().grid(row=0,column=6,rowspan=16,columnspan=13,padx=5,pady=10,sticky='NSEW')
self.det_canvas._tkcanvas.grid(sticky='nsew',padx=10)
self.det_canvas._tkcanvas.config(highlightbackground='grey64',highlightthickness=1)
# progress bar
self.style = ttk.Style(self)
self.style.layout('text.Horizontal.TProgressbar',[('Horizontal.Progressbar.trough',{'children': [('Horizontal.Progressbar.pbar',{'side': 'left','sticky': 'ns'})],'sticky': 'nsew'}),('Horizontal.Progressbar.label',{'sticky': 'ns'})])
self.style.configure('text.Horizontal.TProgressbar',text='0.0 %',font=('Times',12))
self.progress = ttk.Progressbar(self,orient=HORIZONTAL,mode='determinate')
self.progress.configure(style='text.Horizontal.TProgressbar')
self.progress.grid(row=18,rowspan=1,columnspan=20,padx=10,pady=5,sticky='NSEW')
# inserts space between lumeda logo and username label
self.grid_rowconfigure(17,weight=1) # weight controls number of spaces
self.grid_rowconfigure(19,weight=1) # weight controls number of spaces
style = ttk.Style()
style.configure('green.TButton',background='green4',font='bold',foreground='green4',highlightcolor='green4')
self.start_btn = ttk.Button(self,text="START",style='green.TButton',command=lambda: self.start_treatment())
self.start_btn.grid(row=20,column=5,columnspan=1,sticky='nsew')
class Page2(tk.Frame):
def __init__(self,parent)
if __name__ == '__main__':
root = APP()
root.geometry("720x460")
root.resizable(0,0)
root.mainloop()
解决方法
最终使用 after() 函数,一切正常。谢谢!