【问题标题】:GUI triggering actions in a separate processGUI 在单独的进程中触发操作
【发布时间】:2020-03-19 11:31:44
【问题描述】:

我在使用 python-multiprocessing 和 Tkinter GUI 时遇到问题。 我有两个进程:

  • main,循环运行 Tkinter GUI
  • 完成所有其他任务的第二个过程

以下是我正在努力解决的问题:

  1. 我想通过单击 GUI 按钮来触发操作(例如,在第二个进程中启动特定任务)。
  2. 然后,当用户单击该按钮并启动第二个进程中的任务时,GUI 将窗口更改为新窗口(已经知道如何更改窗口)。在新的按钮中还有一堆按钮,但我希​​望它们在第二个进程中的任务完成之前是不可点击的(或者点击时什么都没有)。

最好的方法是什么?

编辑:在我开始使用多处理之前,我的按钮和触发函数的代码如下所示:

button48g = tk.Button(self, text='48g', height = 10, width = 20, font=("Courier", 20), bg="WHITE", command=lambda: controller.show_frame(GUI.PageOne48g))
button48g.bind('<Button-1>', GUI.commands.leftClick)

其中 leftClick 是一个函数,例如

def leftClick(event):
    print('Left click!')

现在,leftClick 函数在另一个进程中,称为“测试”。

queueTestResults = multiprocessing.Queue()
test = multiprocessing.Process(name='test', target=testProcess, args=(queueTestResults,))
test.start()

gui = GUI.GuiApp()
gui.root.mainloop()

while queueTestResults.empty():
    pass

someResults = queueTestResults.get()
test.join()

【问题讨论】:

  • 请包含一些代码......然后人们会提供建议......但我猜像threading.Thread(target=myTargetFn).start()
  • 我添加了可能有用的代码。感谢您的建议,但它不是多线程而不是多处理的解决方案?

标签: python user-interface tkinter python-multiprocessing


【解决方案1】:

在我看来,使用 2 个队列而不是 1 个队列更容易完成

q_read,q_write = multiprocessing.Queue(),multiprocessing.Queue()

def slow_function():
    time.sleep(5)
    return "Done Sleeping"

def other_process_mainloop(q_write,q_read):
    # this process must get an inverted order
    while 1: # run forever
       while q_read.empty():
           time.sleep(0.1) # waiting for a message
       message = q_read.get()
       if message == "command":
           q_write.put(slow_function())
       else:
           q_write.put("Unknown Command")

# start our worker bee
P = multiprocessing.Process(name="worker",target=other_process_mainloop,
                                    # note inverted order
                            kwargs={q_write:q_read,q_read:q_write)

现在创建一个辅助函数来发送命令并等待响应

def send_command(command_string,callback_fn):
    def check_for_response():
       if q_read.empty():
          return gui.after(200, check_for_response)
       callback_fn(q_read.get())

    q_write.put(command)
    gui.after(200,check_for_response)

# now you can just call this method when you want to send a command

def on_button_clicked(event):
    def on_result(result):
        print("Work is Done:",result)
        gui.lbl.configure(text="All Done!! {}".format(result))            

    gui.lbl.configure(text="Doing some work mate!")
    send_command("command",on_result)

【讨论】:

  • 嗨@Joran Beasley,我认为这也适用于我现在的问题。只想知道单击按钮后这两个功能中的哪一个用于 GUI,哪一个用于功能?谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多