使用 Jupyter notebook——哪个最适合这个 tkinter 算法? quit()、exit()、sys.exit() 或 os.exit()?

Using Jupyter notebook - which is best for this tkinter algrithm? quit(), exit(), sys.exit(), or os.exit()?

我正在使用 Jupyter notebook 编写带有大量“if”语句的 tkinter 算法。

我希望其中一些“if”语句在某些点停止 运行 程序(但不会从 运行 停止 tkinter window)而不返回主程序代码的流动。我写了一个小示例应用程序(如下)来说明我的意思。

我试过使用 quit()、exit()、sys.exit() 和 os.exit()。 quit() 和 exit() 似乎都能正常工作,正如预期的那样,他们说“嗨”而不是“再见”。但是当我关闭 tkinter window 时,我仍然得到一些不需要的读数——我认为这可能比 python 或 tkinter 更多的是 Jupyter 错误。它通常说,“内核似乎已经死了。它将自动重新启动。”

示例脚本包含上面的每个命令,它使用注释“#”来打开和关闭该行。每个案例的不需要的读数和消息也在脚本中的代码旁边进行了注释。

我担心的是,如果我进一步编写代码,不需要的读出是否会造成问题甚至安全威胁,因为其中一些 if 语句将用于密码保护区域。我假设如果不需要的消息来自 Jupyter,那么一旦我将代码编译为 exe,这些消息将是良性且透明的,我的假设是否正确?

我的代码如下:

import tkinter
from tkinter import * 
import tkinter as tk

import sys
import os

def routine ():
    
    x = 0

    if x < 1:

        print("Hi")

    # quit()  # Prints Hi and not bye; 
              # when destroyed, it says Kernel Restarting
              # The kernel appears to have died. It will restart automatically.
            
    # exit()  # On an apparent level - it seems to do all the same things as quit.
    
    # sys.exit()    # Prints Hi
                    # and then...
                    # An exception has occurred, use %tb to see the full traceback.
                    # SystemExit
                    # Then the entire systems, including the tkinter window, 
                    # locks up and spin doing nothing.
                    # The close button wont even work.

    # os._exit()  # Exception in Tkinter callback
                # Traceback (most recent call last):
                # File "C:\Users\rrr\lib\tkinter\__init__.py", line 1705, in __call__
                # return self.func(*args)
                # File "<ipython-input-3-c9d340ae6a31>", line 31, in routine
                # os._exit()
                # TypeError: _exit() missing required argument 'status' (pos 1)

    if x > 1:

        print("bye...")


root = Tk()  
root.geometry("300x200+200+200")

btn1 = Button(root, text ="Run A Routine", command = routine)
btn1.pack(pady = 20, anchor='center')

btn1 = Button(root, text ="Close Window", command = root.destroy)
btn1.pack(pady = 20, anchor='center')

root.mainloop()

我想知道“停止 运行 程序”是什么意思?你的意思是退出你写的 function/subroutine 吗?因为如果是这种情况,您应该简单地使用 return 退出定义的例程。

如果你想做一些更复杂的事情,你可能需要删除你的 .mainloop() 更新 tkinter 的调用,而是使用类似下面的东西:

RUN_FLAG = True
while RUN_FLAG:
    root.update_idletasks()
    root.update()
    time.sleep(0.01)

这将允许您更新子例程中的全局变量 RUN_FLAG 并使用它来超越您的 tkinter,然后完成您的脚本。

另外,旁注; 运行 在我看来,Jupyter 中的 tkinter 有点奇怪。如果您的解决方案变得更加广泛,您可能会从标准 python 脚本中获得更好的性能。我推荐 JetBrains 的“PyCharm”作为 IDE。

Angus B:我喜欢你关于使用 return 的想法,我不知道我能做到 - 因为我在编程方面还是太新了。但它似乎像我想要的那样工作。下面的代码演示了我的意思。

如果你按原样运行,那么它会在第 7 行的 return 命令处停止,并会在命令行打印“Hi A”。

但是如果你注释掉第 7 行,那么它会打印

“嗨A” “嗨 B”

我不太明白使用 return 与使用 exit 或 quit 之间的区别,但 return 似乎能做更多我想做的事情。我会继续研究它。感谢您的答复。 :)

郑重声明,我的问题可能不是前沿研究,但有点不同并且已经得到解答。如果你愿意,我们可以继续讨论。

import tkinter

def routine (x):
    
    if x == "A":
        print("Hi A1")
        return
        
    if x == "B":
        print("Hi B")
    
    if x == "A":
        print("Hi A2")        
            
root = Tk()  
root.geometry("300x200+200+200")

btn1 = Button(root, text ="Run A Routine", command = lambda: routine("A"))
btn1.pack(pady = 20, anchor='center')

btn1 = Button(root, text ="Close Window", command = root.destroy)
btn1.pack(pady = 20, anchor='center')

root.mainloop()