Python 3.x 文本小部件打开后,tkinter GUI崩溃/在关闭时不响应
现在,当我按下“时间范围”按钮并调用calculateTime函数后,文本小部件将显示我插入其中的结果。然而,在那之后,每当我关闭GUI窗口时,程序就会冻结,我将不得不被迫退出它。这是我的代码:Python 3.x 文本小部件打开后,tkinter GUI崩溃/在关闭时不响应,python-3.x,tkinter,Python 3.x,Tkinter,现在,当我按下“时间范围”按钮并调用calculateTime函数后,文本小部件将显示我插入其中的结果。然而,在那之后,每当我关闭GUI窗口时,程序就会冻结,我将不得不被迫退出它。这是我的代码: import tkinter from tkinter import * import math from tkinter import messagebox class MyClass(tkinter.Frame): def __init__(self, *args, **kwargs):
import tkinter
from tkinter import *
import math
from tkinter import messagebox
class MyClass(tkinter.Frame):
def __init__(self, *args, **kwargs):
tkinter.Frame.__init__(self, *args, **kwargs)
#Setting up frame and widgets
vcmd1 = (self.register(self.__vcmd1), '%P', '%S')
vcmd2 = (self.register(self.__vcmd2), '%P')
vcmd3 = (self.register(self.__vcmd3), '%P', '%S')
label_iso = Label(self,text="Isotope A, Element")
label_vol = Label(self, text="Voltage")
label_range = Label(self, text="Charge Range")
label_iso.grid(row=0, column=0, sticky=E)
label_vol.grid(row=1, column=0, sticky=E)
label_range.grid(row=2, column=0, sticky=E)
self.entry1 = tkinter.Entry(self, validate="key", validatecommand=vcmd1)
self.entry2 = tkinter.Entry(self, validate="key", validatecommand=vcmd2)
self.entry3 = tkinter.Entry(self, validate="key", validatecommand=vcmd3)
self.entry1.grid(row=0, column=1)
self.entry2.grid(row=1, column=1)
self.entry3.grid(row=2, column=1)
def __vcmd1(self, P, S):
validString = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM,1234567890'
if not S in validString:
return False
if "," in P:
if (len(P) - 1) > len(P.replace(",","")):
return False
messagebox.showinfo("Error", "Expected Form: ex. 133,Cs")
else:
return True
def __vcmd2(self, P):
if P == '':
return True
try:
float(P)
return True
except ValueError:
messagebox.showinfo("Error", "Entry is not a float or integer")
return False
def __vcmd3(self, P, S):
if "," in P:
if len(P.split(",")) > 2:
return False
a = P.split(",")[0]
b = P.split(",")[1]
if a != '' and b != '':
try:
int(a)
int(b)
except ValueError:
messagebox.showinfo("Error", "Expected form: ex. 1,12")
return False
else:
return True
class TimeGenerator:
def __init__(self,master):
frame = MyClass(master)
frame.grid(columnspan=2)
button = Button(root, text='Time Range', command=self.calculateTime)
button.grid(row=3, columnspan=2)
self.text = Text(root)
self.iso = frame.entry1
self.vol = frame.entry2
self.r = frame.entry3
def calculateTime(self):
x = 5
if self.r.get() == "" or self.iso.get() == "" or self.vol.get() == "":
messagebox.showinfo("Error", "No field can be empty")
return None
self.iso = self.iso.get().replace(" ", "")
list = []
for e in self.iso.split(","):
list.append(e)
f = open("/Users/LazyLinh/PycharmProjects/mass.mas12.txt", "r")
i = 0
while (i < 40):
header = f.readline()
i += 1
self.mass = 0
#iterate through text file
for line in f:
line = line.strip()
columns = line.split()
if (list[0] == columns[3]):
if (list[1].lower() == columns[4].lower()):
if (len(columns) == 16):
self.mass = float(columns[13].replace("#","")) + float(columns[14].replace("#",""))
else:
self.mass = float(columns[12].replace("#","")) + float(columns[13].replace("#",""))
#Calculation
self.r = self.r.get().replace(" ", "")
tup = tuple(int(x) for x in self.r.split(","))
list = []
for q in range(tup[0], tup[1] + 1):
y = (x * math.sqrt(self.mass * 1.6605402e-27 / (2 * q * float(self.vol.get())))) * 10e6
list.append(y)
i = tup[0]
#inserting to text widget
for time in list:
self.text.insert("end", "%d: %s\n" % (i, time))
i = i + 1
self.text.pack()
root = Tk()
b = TimeGenerator(root)
root.mainloop()
导入tkinter
从tkinter进口*
输入数学
从tkinter导入消息框
类MyClass(tkinter.Frame):
定义初始化(self,*args,**kwargs):
tkinter.Frame.\uuuu init\uuuu(self,*args,**kwargs)
#设置框架和小部件
vcmd1=(self.register(self.\u vcmd1),'%P','%S')
vcmd2=(self.register(self.\u vcmd2),“%P”)
vcmd3=(self.register(self.\u vcmd3),'%P','%S')
标签\u iso=标签(self,text=“同位素A,元素”)
label\u vol=标签(self,text=“电压”)
标签\范围=标签(自我,text=“收费范围”)
标签网格(行=0,列=0,粘性=E)
标签卷网格(行=1,列=0,粘性=E)
label_range.grid(行=2,列=0,粘性=E)
self.entry1=tkinter.Entry(self,validate=“key”,validatecommand=vcmd1)
self.entry2=tkinter.Entry(self,validate=“key”,validatecommand=vcmd2)
self.entry3=tkinter.Entry(self,validate=“key”,validatecommand=vcmd3)
self.entry1.grid(行=0,列=1)
self.entry2.grid(行=1,列=1)
self.entry3.grid(行=2,列=1)
def__vcmd1(自身、P、S):
有效字符串='qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM,1234567890'
如果不在有效字符串中:
返回错误
如果“,”在P中:
如果(len(P)-1)>len(P.replace(“,”,”):
返回错误
messagebox.showinfo(“错误”,“预期形式:ex.133,Cs”)
其他:
返回真值
def__vcmd2(自身,P):
如果P='':
返回真值
尝试:
浮动(P)
返回真值
除值错误外:
messagebox.showinfo(“错误”,“条目不是浮点或整数”)
返回错误
def__vcmd3(自身、P、S):
如果“,”在P中:
如果len(P.split(“,”)大于2:
返回错误
a=P.split(“,”[0]
b=P.split(“,”[1]
如果a!=''还有b!='':
尝试:
int(a)
内部(b)
除值错误外:
messagebox.showinfo(“错误”,“预期形式:例1,12”)
返回错误
其他:
返回真值
类时间生成器:
定义初始(自我,主):
帧=MyClass(主)
框架网格(columnspan=2)
按钮=按钮(根,text='Time Range',command=self.calculateTime)
button.grid(行=3,列span=2)
self.text=文本(根)
self.iso=frame.entry1
self.vol=frame.entry2
self.r=frame.entry3
def计算时间(自我):
x=5
如果self.r.get()
messagebox.showinfo(“错误”,“任何字段都不能为空”)
一无所获
self.iso=self.iso.get().replace(“,”)
列表=[]
对于self.iso.split(“,”)中的e:
列表。追加(e)
f=打开(“/Users/LazyLinh/PycharmProjects/mass.mas12.txt”,“r”)
i=0
而(i<40):
header=f.readline()
i+=1
自身质量=0
#遍历文本文件
对于f中的行:
line=line.strip()
columns=line.split()
如果(列表[0]==列[3]):
如果(列表[1].lower()==列[4].lower()):
如果(len(列)=16):
self.mass=float(列[13]。替换(“#”,”)+float(列[14]。替换(“#”,”)
其他:
self.mass=float(列[12]。替换(“#”,”)+float(列[13]。替换(“#”,”)
#算计
self.r=self.r.get().replace(“,”)
tup=tuple(int(x)表示self.r.split(“,”)中的x)
列表=[]
对于范围内的q(tup[0],tup[1]+1):
y=(x*数学sqrt(自质量*1.6605402e-27/(2*q*浮点(自体积get()))))*10e6
列表。追加(y)
i=tup[0]
#插入到文本小部件
对于列表中的时间:
self.text.insert(“结束”,%d:%s\n“%(i,时间))
i=i+1
self.text.pack()
root=Tk()
b=时间生成器(根)
root.mainloop()
我试图搜索这个主题,但我并没有真正使用任何奇怪的update()函数,函数完成后会显示文本,那么这是一个事件循环问题的可能性有多大?我是否也犯了一些可能导致这个问题的错误
谢谢大家! 根窗口中的小部件同时使用
pack
和grid
。你不能这样做。在给定的容器(根窗口、框架等)中,可以使用其中一个,但不能同时使用两个
程序冻结的原因是pack
和grid
为获得布局控制权而进行的斗争。打包文本小部件时,它会导致根窗口中其他小部件的大小和/或位置发生变化。这将触发grid
尝试重新布局它负责的小部件。这将触发pack
尝试重新布局它负责的小部件,并一直持续到时间结束
我的猜测是,您需要将grid
与self.text
一起使用,因为您在其他任何地方都使用grid