Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
670 views
in Technique[技术] by (71.8m points)

multithreading - how to close a Thread from Tkinter While the Thread is running Python selenium

So, I made a small canvas window with tkinter which has 2 buttons, One is a start button, the other is a stop button. (I'll attach the GUI tkinter code down below. I wont add the Selenium part because I don't want to confuse anyone with mushed up code.) The start button calls a function thats threaded and that launches my "Reporting_Backbone.py" which is a selenium/pyautogui bot that does a bunch of stuff. My problem is that the stop button does not stop the "Reporting_Backbone.py". In the stop button function I've tried sys.exit() but the selenium and the GUI stay open (and running), I've tried daemons (which I might not have been using them correctly because that did nothing)I've tried setting the stop button function to a lambda (which just freezes the GUI, but not the selenium part) and I've tried setting up some kind of a killswitch as a last resort but honestly this thing wont die, its like Thanos fused with Majin Buu. It just keeps running. How do I make it so that the stop button works? I I'm hoping someone can help me with a solution and explanation. I am still new to coding but I am really loving it, if possible I would really like to understand what I am doing wrong. Thank you.

enter code here import tkinter as tk from PIL import Image, ImageTk import time import os import threading import sys

root = tk.Tk()

#Canvas for GUI
canvas = tk.Canvas(root, width=600, height=800)
canvas.grid(columnspan=3, rowspan=4)
canvas.configure(bg="#b9be9c")


#Button Starting
def start_report():
    time.sleep(0.5)
    start_text.set("Armed!")
    os.system("python Reporting_Backbone.py")


#Button Stopping
def stop_craigslist():
    stop_text.set('Stopped')
    time.sleep(3)
    sys.exit()


#Logo
logo = Image.open('Logo.png')
logo = ImageTk.PhotoImage(logo)
logo_label = tk.Label(image=logo)
logo_label.image = logo

#playing logo in window
logo_label.grid(column=1, row=0)
logo_label.configure(bg="#b9be9c")

#instructions
instructions = tk.Label(root, text="Click the 'Start' Button to begin.")
instructions.grid(columnspan=3, column=0, row=1)
instructions.configure(font=("Helvetica", 25) ,bg="#b9be9c")

#Start Button
start_text = tk.StringVar()
start_btn = tk.Button(root, textvariable=start_text, command=threading.Thread(target=start_report).start, font=("Helvetica", 18), fg="black", height=2, width=15)
start_text.set("Start")
start_btn.grid(column=1, row=2)

#Stop Button
stop_text = tk.StringVar()
stop_btn = tk.Button(root, textvariable=stop_text, command=threading.Thread(target=stop_craigslist).start, font=("Helvetica", 18), fg="black", height=2, width=15) #If I set this to a lambda function the Tkinter GUI Freezes up on me
stop_text.set("Stop")
stop_btn.grid(column=1, row=3)


root.mainloop()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You cannot stop the task created by threading.Thread(). Use subprocess instead:

import subprocess

...

proc = None

def start_report():
    global proc
    if proc and not proc.poll():
        print("process is still running")
        return
    proc = subprocess.Popen([sys.executable, "Reporting_backbone.py"])
    start_text.set("Armed!")

def stop_craigslist():
    global proc
    if proc:
        proc.terminate()
        proc = None
        stop_text.set('Stopped')

...
start_btn = tk.Button(root, ..., command=start_report, ...)
...
stop_btn = tk.Button(root, ..., command=stop_craigslist, ...)
...

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...