Python 忘记和销毁帧无效

0 投票
2 回答
1390 浏览
提问于 2025-04-18 07:16

我有一个程序,用来检查用户是否有网络连接。如果没有,程序会显示一个框,上面写着要打开网络连接。然后程序会检查状态是否改变,如果改变了,就会显示登录界面。但是我就是无法去掉 noNetworkConnectionScreen 这个界面。

loadFrame 是显示“启动画面”的框。

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 个回答

-1

是不是需要强制刷新一下屏幕呢?

有时候,pyGTK 需要这样做(不过你是在用 pyGTK 吗?):

while gtk.events_pending(): #   this forces the refresh of the screen
    gtk.main_iteration()
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_forget 或者 pack_forget——一旦小部件被销毁,就不需要做其他任何事情了。

撰写回答