【问题标题】:How to make a button which stops my thread with a while如何制作一个让我的线程停止一段时间的按钮
【发布时间】:2021-08-01 17:40:22
【问题描述】:

我正在尝试制作一个按钮来停止我的线程,其中有一段时间,但我不太确定如何这样做。我基本上只需要停止 while 语句,但我不确定找到停止线程的方法是更好的选择,还是尝试做一些可以停止线程中的 while 的事情,比如使用热键并使用停止按钮pyautogui 按下该热键。我刚开始学习这一切,所以请多多包涵。也非常感谢对我的代码的任何改进! (忽略我的停止按钮命令所说的内容。我只是将它复制并粘贴到那里,看看按钮是否会出现,它确实出现了)

from tkinter import *
from poke import start
import pyautogui
import sys
import threading

myWindow = Tk()
myWindow.title("TFT Bot")
myWindow.configure(background="#EEEEEE")
Label(myWindow, text="TFT Bot", bg="#EEEEEE", fg="#555555", font="Times 20 bold underline").pack()
myWindow.geometry("600x400+200+250")

exitbutton = Button(myWindow, text="Exit", command=myWindow.destroy)
exitbutton.place(x=285,y=100)
      
startbutton = Button(myWindow, text="Start", command=lambda:threading.Thread(target=start).start())
startbutton.place(x=260,y=200)

stopbutton = Button(myWindow, text="Stop", command=lambda:threading.Thread(target=start).start())
stopbutton.place(x=360,y=400)

startbutton.pack()
stopbutton.pack()
exitbutton.pack()

myWindow.mainloop() 

我的开始功能:

from pyautogui import *
import pyautogui
import time
import keyboard
import random
import win32api, win32con
import sys
def start():

    while keyboard.is_pressed('q') == False:
    #PLAY    
        play = pyautogui.locateCenterOnScreen('./images/play.png', confidence = 0.8)
        if play:
            print ("clicking play")
            pyautogui.moveTo(play)
            time.sleep(1)
            pyautogui.click(play, clicks=2, interval=1)
            time.sleep(0.05)

然后它只是一堆看起来类似于第一个 if 语句的行

【问题讨论】:

  • 您需要使用command=lambda:threading.Thread(target=start).start() 将函数作为命令参数传递。否则它将在您单击按钮之前执行该行(在启动时)。你也没有定义任何启动功能。也没有必要说from pyautogui import *import pyautogui,因为你会像这样导入它两次(只使用一个而不是两个)。
  • @sputnick567 实际上启动函数是在from poke import start 中定义的,但我认为 OP 也应该提供有关该启动函数的信息。
  • @Xitiz 是的,谢谢你没看到。
  • @hwangsa 现在我很困惑你的主要问题是什么?因为您的代码中有多个问题。请准确地说出,如果可能的话,简而言之,您的确切问题是什么?
  • @xitiz 我只是想知道一种方法,我可以编写我的停止按钮来停止来自我的开始按钮的线程。

标签: python tkinter


【解决方案1】:

只是为了停止线程,你可以试试这个:

import threading
import time

def run(stop):
    while True:
        print('thread running')
        if stop():
                break
                 
def main():
        stop_threads = False
        t1 = threading.Thread(target = run, args =(lambda : stop_threads, ))
        t1.start()
        time.sleep(1)
        stop_threads = True
        t1.join()
        print('thread killed')
main()

这是基本示例,但与您的问题非常相关。对你来说,你可以这样尝试:

def start(stop):
    while True:
        play = pyautogui.locateCenterOnScreen('./images/play.png', confidence = 0.8)
        if play:
            print ("clicking play")
            pyautogui.moveTo(play)
            time.sleep(1)
            pyautogui.click(play, clicks=2, interval=1)
            time.sleep(0.05)     
            .......
     if stop() :
         break 

stop_threads=False

startbutton = Button(myWindow,text="Start",command=lambda : threading.Thread(target = start, args =(lambda : stop_threads, )).start())

startbutton.place(x=260,y=200)

def test():
    global stop_threads
    stop_threads=True

stopbutton = Button(myWindow, text="Stop", command=test)
stopbutton.place(x=360,y=400)

我创建的线程基本上和你的几乎一样,但不同的是我只使用了一个参数来停止该线程。

有关它的更多信息,您可以访问here,还有一些其他方法可以停止线程。但我发现这对您的代码来说更容易。

【讨论】:

  • 它非常适合我!测试它并通知我它是否工作?
  • @xitix 停止按钮有效,但仅当我在尝试使用机器人的客户端上按 alt 选项卡时才有效。有没有办法在我的开始功能的点击之间停止它?
  • 你说的是什么意思?“我可以在启动函数的点击之间停止它”?您是否要在 x 秒后停止线程?
  • 我只想在按下停止按钮时停止线程,但它只会在我 alt 选项卡单击代码的客户端时停止。所以当 pyautogui 定位到某些东西时,停止按钮不会停止线程。
  • 我的意思是,如果 pyautogui 没有任何东西可以定位,那么停止按钮只会起作用。但我想出了一种让它现在工作的方法,所以我认为我的问题得到了回答,因为它现在与你给我的建议一起工作得很好。感谢您的帮助! @xitiz
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多