【问题标题】:Running a thread with Tkinter object使用 Tkinter 对象运行线程
【发布时间】:2019-09-30 17:07:25
【问题描述】:

当我按下按钮时,scan_open_ports 开始工作,直到 ip_list.curselection() 行停止,该行阻止了函数的运行... 我想知道为什么以及如何解决这个问题? 谢谢

def scan_open_ports():
    #long runtime function
    print "Asdasd\"
    ip_list.curselection()
def thr_open_ports():
    threading.Thread(target=scan_open_ports).start()
ip_list = Listbox()
scan_ports = Button(window, text="Scan Open Ports", command= thr_open_ports, height = 10, width = 20)

【问题讨论】:

  • 你在stackoverflow上找到合适的代码了吗?
  • 也许您可以使用指向该问题/答案的链接以及您说按钮卡住的您自己的代码文本来更新您的问题。
  • 好吧,我认为tkinter 本身并不是多线程的。要与tkinter 交流,我认为您必须使用队列并使用某种机制来轮询该队列并随后对其进行处理。
  • 我试过使用队列,但还是不行……你有什么比线程更好的主意吗?
  • 如果您的功能需要很长时间才能运行,并且您仍然需要 GUI 做出响应,则不需要。

标签: python multithreading function user-interface tkinter


【解决方案1】:

我从这个答案中无耻地窃取了一些代码,作为一些tkinter代码的基础:How to align label, entry in tkinter

以下代码对此进行了修改,使其具有 QueueThread,它们仅在按下按钮后运行。

Thread 通过Queuemainloop 通信,root.after() 调用轮询该root.after()

from tkinter import *
from threading import Thread
from queue import Queue
from time import sleep
from random import randint

root = Tk()

root.geometry("583x591+468+158")
root.title("NOKIA _ANSI Performance")
root.configure(borderwidth="1")
root.configure(relief="sunken")
root.configure(background="#dbd8d7")
root.configure(cursor="arrow")
root.configure(highlightbackground="#d9d9d9")
root.configure(highlightcolor="black")

Label3 = Label(root)
Label3.configure(text='''Device  IP Address :''')
Label3.pack()
Label5 = Label(root)
Label5.configure(text='''Username :''')
Label5.pack()

Entry5 = Entry(root)
Entry5.pack()
th = None
q = Queue()

def run_me(q):
    sleep(5)
    q.put(randint(1, 99))

def check_queue():
    if not q.empty():
        item = q.get()
        Label5.configure(text=str(item))
    root.after(200, check_queue)

def do_thread():
    global th
    th = Thread(target=run_me, args=(q,))
    th.start()

Button1 = Button(root)
Button1.configure(pady="0")
Button1.configure(text='''NEXT''')
Button1.configure(command=do_thread)
Button1.pack()
root.after(200, check_queue)
mainloop()

mainloop() 不会被Threadcheck_queue() 所做的轮询阻止。

【讨论】:

  • 您必须按下 NEXT 按钮并等待 5 秒钟,然后才能看到 Username 标签更改文本。在发布之前我确实运行了几次代码。
  • 我刚刚完成了另一项测试,在该测试中我得到了NEXT 按钮,可以直接调用run_me(q)。当我按下按钮时,整个 GUI 挂起 5 秒钟,同时 sleep(5) 执行。使用 Thread 可以解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-24
  • 2016-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-18
相关资源
最近更新 更多