Files
SpiderWithGUI/GUI.py
2020-03-25 11:34:46 +08:00

277 lines
10 KiB
Python

import tkinter as tk
import thread
class EntryWithLabel():
def __init__(self, root, labelValue, default, **kw):
self.root = root
self.labelValue = labelValue
self.default = default
self.frame = tk.Frame(root)
self.label = tk.Label(self.frame, text=labelValue)
self.var = tk.Variable()
self.var.set(default)
self.entry = tk.Entry(self.frame, textvariable=self.var, **kw)
def pack(self, **kw):
self.label.pack(side=tk.LEFT)
self.entry.pack(side=tk.RIGHT)
self.frame.pack(**kw)
return self
def get(self):
return self.var.get()
def set(self, value):
return self.var.set(value)
class LabelWithReadOnlyText():
def __init__(self, root, labelValue, default):
self.root = root
self.labelValue = labelValue
self.var = default
self.frame = tk.Frame(root)
self.label = tk.Label(self.frame, text=labelValue)
self.text = tk.Label(self.frame, text=self.var)
def pack(self, **kw):
self.label.pack(side=tk.LEFT)
self.text.pack(side=tk.RIGHT)
self.frame.pack(**kw)
return self
def set(self, value):
self.var = value
self.text.config(text=self.var)
def get(self):
return self.var
class ProgressBar():
def __init__(self, root, labelValue):
self.frame = tk.Frame(root)
self.label_title = tk.Label(self.frame, text=labelValue)
self.canvas = tk.Canvas(self.frame, width=200, height=22, bg="white")
self.base_line = self.canvas.create_rectangle(2,2,200,23,width = 1,outline = "black", fill="white")
self.fill_line = self.canvas.create_rectangle(2,2,0,23,width = 0,fill = "blue")
self.label_progress = tk.Label(self.frame, width=10)
self.progress = 0
def setProgress(self, progress, text):
if text:
self.label_progress.config(text=text)
if progress < self.progress:
self.canvas.create_rectangle(2,2,200,23,width = 1,outline = "black", fill="white")
self.fill_line = self.canvas.create_rectangle(2,2,0,23,width = 0,fill = "blue")
if progress > 1:
progress = 1
self.progress = progress
self.canvas.coords(self.fill_line, (0, 0, 200*progress, 30))
self.frame.update()
def pack(self, **kw):
self.label_title.pack(side=tk.LEFT)
self.canvas.pack(side=tk.LEFT)
self.label_progress.pack(side=tk.LEFT)
self.frame.pack(**kw)
return self
class BaseInforFrame():
def __init__(self, root):
self.labelframe = tk.LabelFrame(root, text="基本信息")
self.entry_number = EntryWithLabel(self.labelframe, "学号", "2017210281")
self.label_b = LabelWithReadOnlyText(self.labelframe, "B:", 3)
self.label_task = LabelWithReadOnlyText(self.labelframe, "任务:", "B")
self.entry_no = EntryWithLabel(self.labelframe, "本机编号:", 1)
self.entry_total = EntryWithLabel(self.labelframe, "总机器数量:", 1)
self.entry_number.var.trace("w", self._updateNumber)
self.entry_no.var.trace("w", self._updateNo)
self.entry_total.var.trace("w", self._updateTotal)
def disable(self):
self.entry_no.entry.config(state="disable")
self.entry_number.entry.config(state="disable")
self.entry_total.entry.config(state="disable")
def normal(self):
self.entry_no.entry.config(state="normal")
self.entry_number.entry.config(state="normal")
self.entry_total.entry.config(state="normal")
def pack(self, **kw):
self.entry_number.pack()
self.label_b.pack()
self.label_task.pack()
self.entry_no.pack()
self.entry_total.pack()
self.labelframe.pack(**kw)
return self
def _bToTask(self, b):
if b > 2:
return "B"
else:
return "A"
def inputToInt(self, entry):
textcheck = str(entry.get())
textcheck = ''.join(i for i in textcheck if i in '0123456789')
if textcheck == '':
return None
return int(textcheck)
def _updateNumber(self, *args):
number = self.inputToInt(self.entry_number)
if number == None:
return
try:
self.entry_number.set(number)
b = number % 19
self.label_b.set(b)
self.label_task.set(self._bToTask(b))
return False
except:
pass
def _updateNo(self, *args):
no = self.inputToInt(self.entry_no)
total = self.inputToInt(self.entry_total)
if no == None or total == None:
return
if no > total:
self.entry_no.set(total)
elif no < 1:
self.entry_no.set(1)
else:
self.entry_no.set(no)
def _updateTotal(self, *args):
total = self.inputToInt(self.entry_total)
if total == None:
return
if total < 1:
total = 1
self.entry_total.set(total)
class SpiderStatus():
def __init__(self, root):
self.labelframe = tk.LabelFrame(root, text="爬取结果")
self.text_info = tk.Text(self.labelframe, width= 100, height= 20)
def pack(self, **kw):
self.text_info.pack()
self.labelframe.pack(**kw)
def set(self, text):
# self.text_info.delete('1.0','end')
self.text_info.insert('end', text+"\n")
self.text_info.see(tk.END)
class Timmer():
def __init__(self, root, start, stop):
self.pause = False
self.start = False
self.sleeptime = 4.0
self.maxoffset = 212
self.startP = start
self.stop = stop
self.labelframe = tk.LabelFrame(root, text="计时器")
self.progress_each = ProgressBar(self.labelframe, "每次计时:")
self.progress_totle = ProgressBar(self.labelframe, "总进度:")
self.entry_sleepTime = EntryWithLabel(self.labelframe, "每次延时(s):", self.sleeptime)
self.entry_maxOffset = EntryWithLabel(self.labelframe, "最大偏移:", self.maxoffset)
self.btnframe = tk.Frame(self.labelframe)
self.button_startStop = tk.Button(self.btnframe, text="开始", command=self.startStop)
self.button_pause = tk.Button(self.btnframe, text="暂停", command=self._pause, state="disable")
self.entry_sleepTime.var.trace("w", self._updateSleepTime)
self.entry_maxOffset.var.trace("w", self._updateMaxOffset)
def pack(self, **kw):
self.progress_each.pack()
self.progress_totle.pack()
self.entry_sleepTime.pack()
self.entry_maxOffset.pack()
self.button_startStop.pack(side=tk.LEFT)
self.button_pause.pack(side=tk.LEFT)
self.btnframe.pack()
self.labelframe.pack(**kw)
def inputToInt(self, entry):
textcheck = str(entry.get())
textcheck = ''.join(i for i in textcheck if i in '0123456789')
if textcheck == '':
return None
return int(textcheck)
def inputToFloat(self, entry):
textcheck = str(entry.get())
textcheck = ''.join(i for i in textcheck if i in '0123456789.')
if textcheck == '':
return None
if textcheck.count('.') > 1:
first = textcheck.find('.')
second = textcheck.find('.', first+1)
textcheck = textcheck[0:second]
return float(textcheck)
def _updateSleepTime(self, *args):
sleeptime = self.inputToFloat(self.entry_sleepTime)
if sleeptime == None:
return
self.sleeptime = sleeptime
self.entry_sleepTime.set(self.sleeptime)
def _updateMaxOffset(self, *args):
maxoffset = self.inputToInt(self.entry_maxOffset)
if maxoffset == None:
return
self.maxoffset = maxoffset
self.progress_totle.setProgress(int(self.progress_totle.label_progress.config("text")[-1])/self.maxoffset, None)
self.entry_maxOffset.set(self.maxoffset)
def startStop(self):
if self.start and not self.pause: # 停止
self.start = False
self.pause = False
self.stop()
self.button_startStop.config(text="开始")
self.button_pause.config(state="disable")
elif not self.start and not self.pause: # 开始
self.start = True
self.pause = False
self.startP()
self.button_startStop.config(text="停止")
self.button_pause.config(state="normal")
elif self.start and self.pause: # 继续
self.start = True
self.pause = False
self.button_startStop.config(text="停止")
self.button_pause.config(state="normal")
def _pause(self):
self.button_pause.config(state="disable")
self.button_startStop.config(text="继续")
self.pause = True
class MainGui():
def __init__(self, backend):
self.root = tk.Tk()
self.root.title("Web搜索技术第一次作业")
self.backend = backend
self.thread = None
self.topFrame = tk.Frame(self.root)
self.baseinfo = BaseInforFrame(self.topFrame)
self.timmer = Timmer(self.topFrame, self.startThread, self.stopThread)
self.spiderstatus = SpiderStatus(self.root)
def start(self):
self.baseinfo.pack(side=tk.LEFT)
self.timmer.pack(side=tk.LEFT)
self.topFrame.pack()
self.spiderstatus.pack()
self.timmer.progress_totle.setProgress(self.backend.getOffset()/self.timmer.maxoffset, str(self.backend.getOffset()))
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
self.root.mainloop()
def on_closing(self):
if self.thread and self.thread.is_alive():
self.thread.terminate()
thread.stop_thread(self.thread)
self.thread.join()
self.root.destroy()
def startThread(self):
self.baseinfo.disable()
self.backend.config.data["number"] = self.baseinfo.inputToInt(self.baseinfo.entry_number)
self.backend.config.data["totle"] = self.baseinfo.inputToInt(self.baseinfo.entry_total)
self.backend.config.data["no"] = self.baseinfo.inputToInt(self.baseinfo.entry_no)
self.backend.config.saveData()
self.backend.b = self.baseinfo.label_b.get()
self.backend.task = self.baseinfo.label_task.get()
self.thread = thread.TimmerThread(self.timmer, self.spiderstatus, self.backend)
self.thread.start()
def stopThread(self):
self.baseinfo.normal()