Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Tkinter多线程函数_Python_Multithreading_Tkinter_Imaplib - Fatal编程技术网

Python Tkinter多线程函数

Python Tkinter多线程函数,python,multithreading,tkinter,imaplib,Python,Multithreading,Tkinter,Imaplib,我目前正在使用python中的tkinter库开发一个电子邮件发送和接收程序。 我使用线程模块让程序每60秒刷新一次未读的电子邮件,而你仍然可以继续在程序中做一些事情 线程模块只在执行printsomething命令时工作,我仍然可以继续在程序中执行一些操作。然而,当我让线程登录到gmail并获得未读电子邮件计数时,整个程序冻结并崩溃 下面是我的代码片段。我不会发布完整的代码,我制作了一个简短的版本来展示它的外观 编辑: 在功能上犯了一个小错误。已删除get_凭据 import tkinter,

我目前正在使用python中的tkinter库开发一个电子邮件发送和接收程序。 我使用线程模块让程序每60秒刷新一次未读的电子邮件,而你仍然可以继续在程序中做一些事情

线程模块只在执行printsomething命令时工作,我仍然可以继续在程序中执行一些操作。然而,当我让线程登录到gmail并获得未读电子邮件计数时,整个程序冻结并崩溃

下面是我的代码片段。我不会发布完整的代码,我制作了一个简短的版本来展示它的外观

编辑: 在功能上犯了一个小错误。已删除get_凭据

import tkinter, re, threading, time, imaplib, too many to list here.
class Application(Frame):

def __init__(self, parent):
        ... Start some functions
        ... Create some widgets
        ... Create some global stringvars for entry fields

def threadrefresh(self):#I want to start this function when a button is clicked

        def multithreading():

            usernamevar = "Username"
            passwordvar = "Password"

            obj = imaplib.IMAP4_SSL('imap.gmail.com', '993') #connect to gmail
            obj.login(usernamevar, passwordvar) #log in
            obj.select() #select the inbox
            unread = str(len(obj.search(None, 'UnSeen')[1][0].split())) #get the total unread
            print(unread)
            obj.close()

            time.sleep(3)
            multi = threading.Thread(target=multithreading)
            multi.start()

        multi = threading.Thread(target=multithreading)
        multi.start()

def other_functions_that_do_not_matter_in_this_case():
    ... Creating GUI
    ... Sending mail
    ... Etc.
    ... Create a button with function call self.threadrefresh


def main():
    root = Tk()
    app = Application(root)
    root.mainloop()

if __name__ == '__main__':
    main() 

这个代码真的正确吗

在多线程处理中称之为:

time.sleep(3)
multi = threading.Thread(target=multithreading)
multi.start()
你基本上是告诉每个线程在3秒钟后创建一个自己的副本。。。我认为你没有抓住要点。您可能应该在while循环中运行一个线程,该循环从数据库获取数据

每当您希望线程对某个对象执行操作时,就将其添加到队列中

编辑:示例代码

import threading
import Queue
import time

def f(q):
    while True:
        print q.get() #block thread until something shows up

q = Queue.Queue()
t = threading.Thread(target=f,args=[q])
t.daemon = True #if parent dies, kill thread
t.start()
for x in range(0,1000):
    q.put(x)
    time.sleep(1)

这个代码真的正确吗

在多线程处理中称之为:

time.sleep(3)
multi = threading.Thread(target=multithreading)
multi.start()
你基本上是告诉每个线程在3秒钟后创建一个自己的副本。。。我认为你没有抓住要点。您可能应该在while循环中运行一个线程,该循环从数据库获取数据

每当您希望线程对某个对象执行操作时,就将其添加到队列中

编辑:示例代码

import threading
import Queue
import time

def f(q):
    while True:
        print q.get() #block thread until something shows up

q = Queue.Queue()
t = threading.Thread(target=f,args=[q])
t.daemon = True #if parent dies, kill thread
t.start()
for x in range(0,1000):
    q.put(x)
    time.sleep(1)

也许tkinter不喜欢多线程。Tkinter带来了一个Tk.after方法,该方法在给定时间后调用函数。也许这已经符合你的需要了。@IchUndNichtDu我更喜欢在后台运行线程。我已经在线程每隔几秒钟打印一个字符串方面取得了一些成功,而我仍然可以使用我的程序。在tk.Var上使用跟踪方法。将它指向一个函数,该函数向另一个线程搜索的队列中添加了一些内容。请看我的答案。也许tkinter不喜欢多线程。Tkinter带来了一个Tk.after方法,该方法在给定时间后调用函数。也许这已经符合你的需要了。@IchUndNichtDu我更喜欢在后台运行线程。我已经在线程每隔几秒钟打印一个字符串方面取得了一些成功,而我仍然可以使用我的程序。在tk.Var上使用跟踪方法。将它指向一个函数,该函数向另一个线程搜索的队列中添加了一些内容。请参阅我的答案。我在后台运行该线程后尝试了此操作,但没有再次调用自己。还尝试了一个forloop和time.sleep。如果我不把线程再次在我只是调用该函数在最后一次。编辑:不过我会尝试队列方法。这绝对是进入队列的方式。您只需使用queue.get在顶部执行while循环。它将阻塞线程,直到它获取数据。一旦它得到数据,你就可以用它做任何事情。完成后,它将返回并等待更多数据。谢谢!我真的不知道这个函数存在。每当我收到新的邮件更新时,我肯定会想起你:嘿,我一直在尝试一些关于队列的事情,但在网上找不到一个简单的解释。我该如何构造这样的东西呢?可能是这样的:我建议只编写一些测试代码来启动从队列读取的线程。一旦你理解了这个原理,这就很容易了。好吧,我在后台运行线程后就尝试了这个方法,没有再次调用自己。还尝试了一个forloop和time.sleep。如果我不把线程再次在我只是调用该函数在最后一次。编辑:不过我会尝试队列方法。这绝对是进入队列的方式。您只需使用queue.get在顶部执行while循环。它将阻塞线程,直到它获取数据。一旦它得到数据,你就可以用它做任何事情。完成后,它将返回并等待更多数据。谢谢!我真的不知道这个函数存在。每当我收到新的邮件更新时,我肯定会想起你:嘿,我一直在尝试一些关于队列的事情,但在网上找不到一个简单的解释。我该如何构造这样的东西呢?可能是这样的:我建议只编写一些测试代码来启动从队列读取的线程。一旦你理解了原理,这就很容易了。