首页 > 解决方案 > 为什么我的程序在使用 tkinter 的 after 函数时会崩溃?

问题描述

import socket
import time
import tkinter as tk
from tkinter import StringVar
from functools import partial
import Client
import json
LARGE_FONT= ("Verdana", 8)



class MainGUI(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)

        container.pack(side="top", fill="both", expand=True)

        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (ConnectionPage, SystemPage):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(ConnectionPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()
    def show_error(self, cont, error):
        frame = self.frames[cont]
        ErrorLabel = tk.Label(frame,text=error,font=LARGE_FONT)
        ErrorLabel.pack()
        ErrorLabel.after(2500,lambda :ErrorLabel.destroy())
    def show_json_info(self,cont,sock):
        frame = self.frames[cont]
        packet = sock.recv(2000).decode()
        JsonDict = json.loads(packet)
        SysInfoLabel = tk.Label(frame, text="System Info", font=LARGE_FONT)
        SysInfoLabel.pack(pady=10, padx=10)
        SysInfoText = tk.Text(frame)
        SysInfoText.pack()
        SysInfoText.config(font=LARGE_FONT)
        SysInfoText.insert("end","System: "+JsonDict["System"]+'\n')
        SysInfoText.insert("end","NodeName: " + JsonDict["NodeName"]+'\n')
        SysInfoText.insert("end","Release: "+JsonDict["Release"]+'\n')
        SysInfoText.insert("end","Version: "+JsonDict["Version"]+'\n')
        SysInfoText.insert("end","Machine: "+JsonDict["Machine"]+'\n')
        SysInfoText.insert("end","Processor: "+JsonDict["Processor"]+'\n')
        frame.after(2500,self.show_json_info,SystemPage,sock)
class ConnectionPage(tk.Frame):
    def InitiateConnection(self,controller, Ip,Port):
        sock = Client.CheckAddress(Ip,Port)
        if sock:
            controller.show_frame(SystemPage)
            controller.show_json_info(SystemPage, sock)
        else:
            controller.show_error(ConnectionPage, "Wrong Ip or port")


    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Connection Page", font=LARGE_FONT)
        label.pack(pady=10,padx=10)
        IpLabel = tk.Label(self, text="Ip address")
        IpLabel.pack()
        Ip = StringVar()
        IpEntry = tk.Entry(self, textvariable=Ip)
        IpEntry.pack()

        PortLabel = tk.Label(self, text="Port")
        PortLabel.pack()
        Port = StringVar()
        PortEntry = tk.Entry(self, textvariable=Port)
        PortEntry.pack()
        cmd = partial(self.InitiateConnection,controller,Ip,Port)
        ConnectButton = tk.Button(self, text="Connect", command=cmd)
        ConnectButton.pack()


class SystemPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        BackToConnectionButton = tk.Button(self, text="Back to Connection Page",command=lambda: controller.show_frame(ConnectionPage))
        BackToConnectionButton.pack()


if __name__ == "__main__":
    app = MainGUI()
    app.mainloop()

该函数show_json_info()应该在每次运行时更新当前窗口,当尝试使用常规循环时程序崩溃,所以我使用了 tkinter 的 after 函数。但同样的事情发生了,程序崩溃了。知道为什么会这样吗?我可以用来解决问题的任何替代方法吗?

ps 函数Client.CheckAddress()返回一个套接字,我从中接收输入。

标签: pythonsocketstkintercrash

解决方案


推荐阅读