Python忘记并破坏框架无法正常工作

时间:2014-05-22 07:30:40

标签: python tkinter

我有一个程序,我检查用户是否有活动的网络连接。如果没有,程序会显示一个框架,表示打开互联网连接。程序检查状态是否已更改,如果是,则显示登录屏幕。但我无法摆脱noNetworkConnectionScreenloadFrame是显示“splashscreen”的框架。

class AppUI(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.parent.title("Redux")
        self.loadFrame = Frame(self)
        self.initLogin()

    def initLogin(self):
        internet_is_on = False
        #check 3 times to be sure
        for i in range(3):
            #check the internet connection by pinging to google (returns True or False)
            if db.internetOn():
                internet_is_on = True
        if internet_is_on:
            self.initLoginScreen()
        else:
            self.initLoadScreen()
            thread1 = threading.Thread(target=self.checkNetwork)
            thread1.start()

我还尝试了grid_forget,崩溃了:

def checkNetwork(self):
    internet_is_off = True
    while internet_is_off:
        if db.internetOn():
            internet_is_off = False
            self.loadFrame.pack_forget()
            self.loadFrame.destroy()
            self.initLoginScreen()
        else:
           time.sleep(2)

在这里我初始化了加载屏幕:

def initLoadScreen(self):
    self.loadFrame.grid(row=0, column=0, pady=(150,0))

    self.lblUser = Label(self.loadFrame, text="HI", font=('Arial', 60), foreground="#666666")
    self.lblUser.grid(row=0, column=0)

    self.canvas = Canvas(self.loadFrame, width = 121, height = 81)
    self.canvas.grid(row=1, column=0)
    self.loader = PhotoImage(file = 'loader.gif')
    self.canvas.create_image(121, 81, image = self.loader, anchor = NW)

    self.lblNetwork = Label(self.loadFrame, text="please make sure you have an active network connection", font=('Arial', 16), foreground="#666666")       
    self.lblNetwork.grid(row=2, column=0)

我可以看到来自lblNetwork的字母在两侧被切掉,但框架并没有消失。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

销毁小部件和/或“忘记”它是从屏幕上移除小部件的正确方法。几乎可以肯定,问题与您使用线程有关。 Tkinter不是线程安全的,只能在一个线程中使用。如果在一个线程中创建小部件,则不应尝试从任何其他线程使用它们。在这种情况下,您试图从除创建它之外的线程中销毁一个帧。

您需要做的是在线程之间建立某种通信 - 队列或共享(非Tkinter)变量。由于您只是检查布尔标志,因此一个简单的共享变量将起作用。在主程序中,您可以使用主线程中基于after的简单循环检查此变量:

def check_network(self):
    if the_network_is_down:
        <display a message>
    else:
        <remove the message>

    # check once a second
    self.after(1000, self.check_network)

此外,如果您在窗口小部件上调用destroy,则无需调用grid_forgetpack_forget - 一旦窗口小部件被销毁,您无需执行任何其他操作。

答案 1 :(得分:-1)

难道你必须强行刷新屏幕吗?

pyGTK有时需要这个(但你使用的是pyGTK吗?):

while gtk.events_pending(): #   this forces the refresh of the screen
    gtk.main_iteration()