我已经制作了一个tkinter应用程序,我有一个提交按钮,当我按下此按钮时,爬行请求转到request.get(url)方法,它从爬行开始,tkinter变为非活动状态,直到它给了我响应。但我希望在tkinter应用程序中另一个按钮“停止”,当按下时停止进程在后台进行,下次我想要我可以按提交按钮再次启动过程。 我已经尝试了破解和退出tkinter中可用的方法,但它们关闭了tkinter小部件本身。 我的代码是: -
#!/usr/bin/python
# -*- coding: latin-1 -*-
from Tkinter import *
import thread
from tool_crawler import *
import tkMessageBox
import ttk
# function which accepts url from GUI and pass it further for the
def crawl(url):
time_delay = time_delay_box.get()
if url == "Please enter URL.......":
tkMessageBox.showerror("Error(错误)", "Please enter a valid URL(请输入有效网址)")
elif not url:
tkMessageBox.showerror("Error(错误)", "Please enter a valid URL(请输入有效网址)")
else:
tree.heading("#0", text=url)
links = find_links(url, time_delay)
#print links
for i, link in enumerate(links):
tree.insert("", i, str(i), text=link)
tree.bind("<Double-1>", OnDoubleClick)
# function will invoke when any node in tree is double clicked
def OnDoubleClick(event):
item = tree.identify('item',event.x,event.y)
url = tree.item(item,"text")
index = tree.index(item)
parent = tree.parent(item)
crawl_child(url,index,parent)
def crawl_child(url,index,parent):
links = find_links(url, time_delay)
#print links
for i, link in enumerate(links):
if not parent:
tree.insert(str(index), i, str(index)+"."+str(i), text=link)
else:
tree.insert(str(parent)+"."+str(index), i, str(parent)+"."+str(index)+"."+str(i), text=link)
# tkinter object
top = Tk()
top.configure(background='Lavender')
# window title
top.title("Fan Wan Crawler ")
# tkinter minimum and maximum size
top.minsize(width=1460, height=800)
top.maxsize(width=1460, height=800)
# url entry area i.e. text box to enter the URLS
url = Entry(top, bd =3, width = 180)
url.insert(0, "Please enter URL.......")
url.pack(side = TOP)
# function to show and hide the text on entry and exit
def default(event):
current = url.get()
if current == "Please enter URL.......":
url.delete ("0", END)
elif not current:
url.insert("0", "Please enter URL.......")
# code to call function default on focusin and focusout
url.bind("<FocusIn>", default)
url.bind("<FocusOut>", default)
# submit button which is performing action on submit
submit = Button(top, text="Submit(提交)", width=15, bg='lightblue', command=lambda: crawl(url.get()))
submit.pack(side = TOP)
# time delay label
time_label = Label(top, text="Time Dealy (时间延迟):", font= ("Helvetica", 12), bg="Lavender", fg = "green")
time_label.place(x=2, y=27)
# time delay Entry
time_delay_box = Spinbox(top, from_=0, to=100, width=3)
time_delay_box.place(x=175, y=27)
# time description
time_label = Label(top, text="(in sec.(以秒为单位))", font=("Helvetica", 12), bg="Lavender", fg = "green")
time_label.place(x=220, y=27)
# tree area
tree = ttk.Treeview(top, selectmode="browse", height= "36")
columns = tree.column("#0", minwidth=0, width=720, stretch=True)
tree.place(x=2,y=56)
top.mainloop()
基本上我调用的是find_links函数,它存在于sepearte文件中并且具有函数request.get来抓取链接,目前我没有使用threads.So,有没有办法在不使用线程的情况下停止这个过程。我不想暂停它,我只想杀死这个过程。
答案 0 :(得分:1)
您可以使用thread
在另一个线程中开始抓取/抓取,然后创建一个暂停/恢复按钮,以启用&#34;暂停&#34;并且&#34; unpausing&#34;通过线程方法threading.Condition
和threading.Lock()
设置线程的一种方法示例,没有创建gui或任何东西只是显示了如何使用可暂停的线程和GUI中的按钮单击的示例,因为您如何选择设置/合并线程会有所不同。这假设在线程处理完当前request.get
调用完成后将发生暂停和恢复。试图阻止线程死在任务中间是一个完全不同的问题。
import threading, requests
import tkinter as tk
def switch_thread_states(widget):
#or whatever pause / resume text you wish for the widget / button
if widget['text'] == 'Pause'
widget['text'] = 'Resume'
else:
widget['text'] = 'Pause'
for thread in threading.enumerate():
if not isinstance(thread, threading._MainThread):
if thread.paused:
thread.resume()
else:
thread.pause()
class PauseableThread(threading.Thread):
def __init__(self, urls):
threading.Thread.__init__(self)
self.urls = urls
self.paused = False
self.pause_cond = threading.Condition(threading.Lock())
def run(self):
for url in self.urls:
with self.pause_cond:
while self.paused:
self.pause_cond.wait()
#make requests here or whatever you're doing
requests.get(url, headers={'User-Agent':'Mozilla/5.0 .....'})
def pause(self):
self.paused = True
self.pause_cond.acquire()
def resume(self):
self.paused = False
self.pause_cond.notify()
self.pause_cond.release()
#make root
#make a button that calls switch_thread_states on press
#spawn threads with urls lists etc