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()