文本窗口小部件打开后,tkinter GUI会在其关闭时崩溃/不响应

时间:2016-05-20 20:16:42

标签: 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):
        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()

我试图搜索这个主题,但我并没有真正使用任何奇怪的update()函数,并且在函数完成后会显示文本,那么它是否有可能是一个事件循环问题?我也做错了会导致这个问题吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

您在根窗口中拥有同时使用packgrid的小部件。你不能做这个。在给定的容器(根窗口,框架等)中,您可以使用其中一个,但不能同时使用两个。

您的程序冻结的原因是packgrid争夺布局控制权。打包文本小部件时,会导致根窗口中其他小部件的大小和/或位置发生更改。这会触发grid尝试重新布局它负责的小部件。这会触发pack尝试重新布局它负责的小部件,并一直打开直到时间结束。

我的猜测是,您需要将gridself.text一起使用,因为您在其他地方使用grid