Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.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中线程完成后再次执行一些操作_Python_Multithreading_Tkinter - Fatal编程技术网

如何创建一个不确定的进程,在后台启动一个线程,并在python中线程完成后再次执行一些操作

如何创建一个不确定的进程,在后台启动一个线程,并在python中线程完成后再次执行一些操作,python,multithreading,tkinter,Python,Multithreading,Tkinter,我正在尝试在Python3的新顶层窗口中为某个进程创建一个不确定的进度条,然后为该进程启动线程。我想要的是,进度条启动,线程也在后台启动,一旦线程完成执行,就会显示一些消息,表明任务已完成 代码: class myThread(threading.Thread): def __init__(self, threadID): threading.Thread.__init__(self) self.threadID = threadID def

我正在尝试在Python3的新顶层窗口中为某个进程创建一个不确定的进度条,然后为该进程启动线程。我想要的是,进度条启动,线程也在后台启动,一旦线程完成执行,就会显示一些消息,表明任务已完成

代码:

class myThread(threading.Thread):
    def __init__(self, threadID):
        threading.Thread.__init__(self)
        self.threadID = threadID


    def run(self):
        print("Starting the thread")
        func()
        print("Ending the thread")

def func():
    some task

...
new_top = Toplevel()
new_top.title("New Top Level")
new_top.geometry("400x170")

label = Label(new_top, text='Doing some work', justify=CENTER, bg="#CBFDCB").place(x=43,y=30)

progress_bar = ttk.Progressbar(new_top, orient="horizontal", mode="indeterminate", takefocus=True, length=320)
progress_bar.place(x=40, y=80)
progress_bar.start()

thread1 = myThread(1)
thread1.start()
thread1.join()

...
执行线程后操作


我的问题是,如果调用thread1.join(),则带有标签和进度条的顶级窗口永远不会出现,如果我跳过这一部分,则线程执行后的操作不会运行。TKinter通过使用无限主循环来等待和处理事件-截取按压、重绘元素等。(查看更多信息)

当您调用
join()
时,您强制主线程(tkinter在其中运行)等待新启动的线程完成执行后再继续,因此无法使用进度条绘制顶级窗口。因此,这实际上不是一个选项


另一方面,您需要知道您的子线程何时完成执行。您可以使用
mythread.isAlive()检查线程是否仍然处于活动状态
,但不能在循环中执行,因为它会再次停止tkinter的主循环的执行,从而绘制接口。我建议寻找解决此问题的方法。

tkinter的工作原理是使用无限主循环来等待和处理事件-截取按下、重新绘制元素等(查看更多信息)

当您调用
join()
时,您强制主线程(tkinter在其中运行)等待新启动的线程完成执行后再继续,因此无法使用进度条绘制顶级窗口。因此,这实际上不是一个选项


另一方面,您需要知道您的子线程何时完成执行。您可以使用
mythread.isAlive()检查线程是否仍然处于活动状态
,但不能在循环中执行,因为它会再次停止tkinter的主循环的执行,从而绘制接口。我建议您考虑处理此问题。

使用tkinter执行线程可能会有点棘手。以下是一些您想要的代码。我的第一个版本无法正常工作,因为我尝试了o从线程的
.run
方法内部销毁Tkinter窗口。这不起作用:窗口关闭,但
.run
方法在
root.destroy
调用后没有进展。因此,现在我们有了一个函数,它每100毫秒检查一次线程是否仍处于活动状态,如果它不处于活动状态,我们将关闭Tkinter窗户

import threading
import tkinter as tk
from tkinter import ttk
from time import sleep

class myThread(threading.Thread):
    def __init__(self, threadID):
        threading.Thread.__init__(self)
        self.threadID = threadID

    def run(self):
        print("Starting the thread")
        func()
        print("Ending the thread")

def func():
    for i in range(10):
        print(i)
        sleep(1)

def check_thread(th):
    if not th.isAlive():
        root.destroy()
    root.after(100, check_thread, th)

root = tk.Tk()
root.title("New Top Level")
root.geometry("400x170")

tk.Label(root, text='Doing some work', justify=tk.CENTER, bg="#CBFDCB").place(x=43, y=30)
progress_bar = ttk.Progressbar(root, orient="horizontal", 
    mode="indeterminate", takefocus=True, length=320)
progress_bar.place(x=40, y=80)
progress_bar.start()

thread1 = myThread(1)
thread1.start()
root.after(100, check_thread, thread1)
root.mainloop()

print("Doing post-thread stuff")

使用Tkinter执行线程处理可能有点棘手。以下是一些您想要的代码。我的第一个版本无法正常工作,因为我试图从线程的
.run
方法内部破坏Tkinter窗口。这不起作用:窗口关闭,但
根目录后,
run
方法没有进展。销毁
调用。因此,现在我们有了一个函数,它每100毫秒检查一次线程是否仍处于活动状态,如果线程不处于活动状态,则关闭Tkinter窗口

import threading
import tkinter as tk
from tkinter import ttk
from time import sleep

class myThread(threading.Thread):
    def __init__(self, threadID):
        threading.Thread.__init__(self)
        self.threadID = threadID

    def run(self):
        print("Starting the thread")
        func()
        print("Ending the thread")

def func():
    for i in range(10):
        print(i)
        sleep(1)

def check_thread(th):
    if not th.isAlive():
        root.destroy()
    root.after(100, check_thread, th)

root = tk.Tk()
root.title("New Top Level")
root.geometry("400x170")

tk.Label(root, text='Doing some work', justify=tk.CENTER, bg="#CBFDCB").place(x=43, y=30)
progress_bar = ttk.Progressbar(root, orient="horizontal", 
    mode="indeterminate", takefocus=True, length=320)
progress_bar.place(x=40, y=80)
progress_bar.start()

thread1 = myThread(1)
thread1.start()
root.after(100, check_thread, thread1)
root.mainloop()

print("Doing post-thread stuff")