简体   繁体   English

tkinter gui在功能失败时冻结

[英]tkinter gui freezes when function fails

Background: To get practice I'm writing an application for work that will allow help desk users to grep | 背景:为了进行练习,我正在编写一个工作应用程序,该应用程序将允许服务台用户使用grep | tail logs without requiring them to perform SSH/terminal work. 尾日志,而无需它们执行SSH /终端工作。 These users are running on windows machines otherwise I'd use subprocess. 这些用户正在Windows计算机上运行,​​否则我将使用子进程。 Some of the servers use system accounts(and those are prefilled into the script), but the others require the user to enter credentials. 一些服务器使用系统帐户(而那些服务器已预先填充到脚本中),但是其他服务器则要求用户输入凭据。

When the script(details below) is run and a user enters their credentials incorrectly the application hangs after throwing a 'No handlers could be found for logger "paramiko.transport"' error. 当运行脚本(详细信息如下)并且用户输入的凭据不正确时,应用程序将在引发“找不到记录程序“ paramiko.transport”的处理程序”错误后挂起。 When the user selects a option that does not have prefilled credentials they are prompted for a username and password. 当用户选择没有预填凭据的选项时,系统会提示他们输入用户名和密码。 The credentials are appended to the appropriate list, the popup is destroyed and the log checking function is called. 凭据将附加到适当的列表,弹出窗口被销毁,并调用日志检查功能。 What might be causing the window to hang when the error is thrown, and what is the best method to handle such issues? 引发错误时,是什么原因导致窗口挂起?什么是解决此类问题的最佳方法?

I have attempted to add logging.basicConfig(), but the application still hangs. 我试图添加logging.basicConfig(),但是应用程序仍然挂起。

Full script: http://pastebin.com/TUvs92yN 完整脚本: http : //pastebin.com/TUvs92yN

When the user first hits the submit button the following is invoked: 当用户第一次单击“提交”按钮时,将调用以下命令:

lambda: credentials() if hosts[log.get()][0] in needs_pass else log_check()

If the host name is found in a list then the credentials box appears. 如果在列表中找到了主机名,则会显示凭据框。 After the user enters their username and password the submit_cred() function is called: 用户输入用户名和密码后,将调用submit_cred()函数:

def submit_cred():
    if len(hosts[log.get()]) < 3:
        hosts[log.get()].append(username_prompt.get())
        hosts[log.get()].append(password_prompt.get())
    prompt.destroy()
    log_check()

This is where the trouble starts. 这是麻烦开始的地方。 If the credentials were correct the application displays the results as expected, but if not when log_check() is called after the window is destroyed an error is received and the application hangs. 如果凭据正确无误,则应用程序将按预期显示结果,但如果不正确,则在销毁窗口后调用log_check()时会收到错误消息,并且应用程序挂起。 I attempted to handle authentication problems in the log_check(), but at this point it doesn't seem to get far enough for that to matter. 我试图在log_check()中处理身份验证问题,但目前看来,这还远远不够。

I believe the issue is with your paramiko ssh connect method call. 我相信问题在于您的paramiko ssh connect方法调用。 The method takes an optional timeout argument, but the timeout is set to None by default and is thus never returning. 该方法采用可选的超时参数,但是超时默认情况下设置为“无”,因此永远不会返回。 If you set this value to something more reasonable for the user, something like 5 seconds (you may want to set that a bit longer in practice): 如果将此值设置为对用户来说更合理,例如5秒(您可能希望在实践中将其设置得更长一点):

# Verify connectivity/authenticate.
    try:
        ssh.connect(host, username=user, password=passwd, timeout=5)

Now you'll notice you'll hit your except clause. 现在,您会注意到您将点击您的except子句。 The exception message will be 'timed out' so you can add a check for that there. 异常消息将“超时”,因此您可以在此处添加检查。

Also, it's not a bad idea to wrap functions like that within a GUI in a Thread to prevent the whole app from freezing, it's pretty easy to implement. 另外,在Thread的GUI中包装类似的功能以防止整个应用程序冻结也不是坏主意,这很容易实现。 In your case, you could do something like rename your current log_check function to _log_check and then write a little wrapper like: 在您的情况下,您可以执行类似将当前log_check函数重命名为_log_check ,然后编写一些包装程序,例如:

def log_check(self):
    t = Thread(target=_log_check)
    t.start()

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM