python线程和进度条

时间:2013-06-15 13:36:39

标签: python multithreading progress-bar ttk nonetype

你好我对python很新,我有一个关于我试图编写的脚本的问题(下面)。 `

import Tkinter as tk
import ttk
import time
import threading
def foo():
    time.sleep(5) # simulate some work
def start_foo_thread():
    global foo_thread
    foo_thread = threading.Thread(target=foo)
    foo_thread.daemon = True
    print("it ran")
    stepprogress.start()
    foo_thread.start()
    root.after(20, check_foo_thread)

def check_foo_thread():
    if foo_thread.is_alive():
        root.after(20, check_foo_thread)
    else:
        stepprogress.stop()
def cancel():
    print("cancelling")
def backround():
    print("running in background")
root = tk.Tk()
frame = tk.Frame(root)
frame.grid()
tk.Label( frame, text="importing").grid(row=1, column=1, columnspan=2)
tk.Label( frame, text="starting").grid(row=2, column=1, columnspan=2)
stepprogress = ttk.Progressbar(frame, orient="horizontal", length=200, mode="determinate").grid(row=3, column=1, columnspan=2)
tk.Label( frame, text="overall progress").grid(row=4, column=1, columnspan=2)
mainprogress = ttk.Progressbar(frame, orient="horizontal", length=200, mode="determinate").grid(row=5, column=1, columnspan=2)
tk.Button(frame, text="Cancel", command=cancel).grid(row=6, column=1)
tk.Button(frame, text="run in background", command=backround).grid(row=6, column=2)
frame.pack()
start_foo_thread()
root.mainloop()

`

以下是我的问题。

1.no matter what I do I always get "nonetype has no attribute start?
2.also I was wondering about how I could safely close the thread and the window when someone hits cancel?
3.I also wondered how I could make it that when someone hits the "background" button the window could close, but not the thread?
4.Is it possible for me to have the process to be threaded in a different file, how so?

我更像是html/javascript编码器,而不是python程序员。

提前致谢, 约翰S

1 个答案:

答案 0 :(得分:3)

1)这是因为您将网格方法的返回分配给 stepprogress ;你可以这样修理它:

stepprogress = ttk.Progressbar(frame, orient="horizontal", length=200, mode="determinate")
stepprogress.grid(row=3, column=1, columnspan=2)

2)您可以使用标志来控制线程的执行,然后在退出之前等待它正确结束:

def foo():
    global load
    i = 1
    while load and i <= 10:
        print("running...")
        time.sleep(1) # simulate some work
        i = i + 1
    print("end of thread")
...
def cancel():
    global load
    load = False
    while foo_thread.is_alive():
        print("waiting thread...")
        time.sleep(0.1)
    print("exiting...")
    root.destroy()

3)您可以使用 root.withdraw()来隐藏窗口:

def backround():
    print("running in background")
    root.withdraw()

以下是一个总结的示例:

import tkinter as tk
import ttk
import time
import threading
def foo():
    i = 1
    while load and i <= 10:
        print("running...")
        time.sleep(1) # simulate some work
        i = i + 1
    print("end of thread")
def start_foo_thread():
    global foo_thread
    foo_thread = threading.Thread(target=foo)
    foo_thread.daemon = True
    print("it ran")
    stepprogress.start()
    foo_thread.start()
    root.after(20, check_foo_thread)

def check_foo_thread():
    if foo_thread.is_alive():
        root.after(20, check_foo_thread)
    else:
        stepprogress.stop()
def cancel():
    global load
    load = False
    while foo_thread.is_alive():
        print("waiting thread...")
        time.sleep(0.1)
    print("exiting...")
    root.destroy()
def backround():
    print("running in background")
    root.withdraw()
root = tk.Tk()
frame = tk.Frame(root)
frame.grid()
load = True
tk.Label( frame, text="importing").grid(row=1, column=1, columnspan=2)
tk.Label( frame, text="starting").grid(row=2, column=1, columnspan=2)
stepprogress = ttk.Progressbar(frame, orient="horizontal", length=200, mode="determinate")
stepprogress.grid(row=3, column=1, columnspan=2)
tk.Label( frame, text="overall progress").grid(row=4, column=1, columnspan=2)
mainprogress = ttk.Progressbar(frame, orient="horizontal", length=200, mode="determinate").grid(row=5, column=1, columnspan=2)
tk.Button(frame, text="Cancel", command=cancel).grid(row=6, column=1)
tk.Button(frame, text="run in background", command=backround).grid(row=6, column=2)
frame.pack()
start_foo_thread()
root.mainloop()

4)你是什么意思“让进程在另一个文件中进行线程化”,在另一个模块中隔离线程函数?...