我是python编码的新手,我一直在从事可以根据所选颜色单击图像的项目。我一直在使用一个程序,当我单击“开始”按钮时,该程序将循环搜索50次。但是,我一直在尝试实现停止按钮,但是问题是当循环运行时,我的代码冻结了。有什么想法吗?
我听说过尝试线程化,但是它看起来非常复杂,而且我无法正确遵循与代码有关的任何教程。顺便说一下,搜索到的图像一直在测试我一直使用的存储在程序文件中的图像。
from imagesearch import *
import pyautogui
import tkinter as tk
from tkinter import *
from tkinter.ttk import *
import time
import threading
# ---Defined Programs---
def run():
global enterColor
enterColor = str(enterColorField.get())
program(enterColor)
def program(color):
whitePos = imagesearch_numLoop(str(color) + ".PNG", 0, 50)
pyautogui.moveTo(whitePos[0] + 20, whitePos[1] + 10)
pyautogui.click()
def stop():
print("Placeholder")
# ---Main Runner---
window = tk.Tk()
window.geometry("250x250")
window.configure(background="#181b54")
app = tk.Frame(window)
app.grid()
enterColorLabel = tk.Label(window, text="Enter Color:", bg="#181b54", fg="white")
enterColorLabel.place(x=10, y=50)
enterColorField = Combobox(window)
enterColorField['values'] = ("Black", "White")
enterColorField.current("0") # set the selected item
enterColorField.place(x=10, y=70)
submitButton = tk.Button(window, text="Start", bg="#66ff00", command=run)
submitButton.place(x=10, y=130)
stopButton = tk.Button(window, text="Stop", bg="red", command=stop)
stopButton.place(x=50, y=130)
window.mainloop()
#---New Python Script---
import cv2
import numpy as np
import pyautogui
import random
import time
def imagesearch_numLoop(image, timesample, maxSamples, precision=0.8):
pos = imagesearch(image, precision)
count = 0
while pos[0] == -1:
print(image+" not found, waiting")
count = count + 1
if count>maxSamples:
break
pos = imagesearch(image, precision)
return pos
每当单击开始时,整个代码就会冻结。我什至无法(x)。
答案 0 :(得分:0)
一个简单的答案是您不能在GUI设计中使用while循环。
但是您可以改用方法.after(delay, callback=None)
。
这里是一个例子:
from tkinter import *
root = Tk()
def loop():
print("Hi!")
root.after(1000, loop) # 1000 is equal to 1 second.
root.after(1000, loop) # This line is to call loop() in 1 second.
root.mainloop()
答案 1 :(得分:0)
这是一个希望简单的多处理配方,将为您服务。我们将有三个主要功能。首先将是一个示例循环,您可以将处理放入其中。我在函数中包含了参数,以向您展示使用多处理时可以传递args和kwargs。
def loop(a, b, c, d):
# Will just sleep for 3 seconds.. simulates whatever processing you do.
time.sleep(3)
return
接下来是一个函数,我们将使用该函数对多处理进程进行排队。
def queue_loop():
p = multiprocessing.Process(target = loop,
args = (1, 2),
kwargs = {"c": 3, "d": 4})
# You can pass args and kwargs to the target function like that
# Note that the process isn't started yet. You call p.start() to activate it.
p.start()
check_status(p) # This is the next function we'll define.
return
然后,您可能会对了解整个过程的执行状态感兴趣。例如,有时希望在运行命令时禁用某些按钮。
def check_status(p):
""" p is the multiprocessing.Process object """
if p.is_alive(): # Then the process is still running
label.config(text = "MP Running")
mp_button.config(state = "disabled")
not_mp_button.config(state = "disabled")
root.after(200, lambda p=p: check_status(p)) # After 200 ms, it will check the status again.
else:
label.config(text = "MP Not Running")
mp_button.config(state = "normal")
not_mp_button.config(state = "normal")
return
将所有内容放到一个片段中
import tkinter as tk
import multiprocessing
import time
def loop(a, b, c, d):
# Will just sleep for 3 seconds.. simulates whatever processing you do.
time.sleep(3)
return
def queue_loop():
p = multiprocessing.Process(target = loop,
args = (1, 2),
kwargs = {"c": 3, "d": 4})
# You can pass args and kwargs to the target function like that
# Note that the process isn't started yet. You call p.start() to activate it.
p.start()
check_status(p) # This is the next function we'll define.
return
def check_status(p):
""" p is the multiprocessing.Process object """
if p.is_alive(): # Then the process is still running
label.config(text = "MP Running")
mp_button.config(state = "disabled")
not_mp_button.config(state = "disabled")
root.after(200, lambda p=p: check_status(p)) # After 200 ms, it will check the status again.
else:
label.config(text = "MP Not Running")
mp_button.config(state = "normal")
not_mp_button.config(state = "normal")
return
if __name__ == "__main__":
root = tk.Tk()
mp_button = tk.Button(master = root, text = "Using MP", command = queue_loop)
mp_button.pack()
label = tk.Label(master = root, text = "MP Not Running")
label.pack()
not_mp_button = tk.Button(master = root, text = "Not MP", command = lambda: loop(1,2,3,4))
not_mp_button.pack()
root.mainloop()
结果是,当您单击“使用MP”按钮时,将禁用命令按钮,并且将在不冻结UI的情况下启动该过程。单击“非MP”按钮将启动“正常”之类的功能,并且将冻结您的UI,就像您在自己的代码中注意到的那样。