def update_label_threhold(*args): """ update_label_threhold. """ logger.debug("args: %s", args) spinbox_value = spinbox.get() self.Label_threshold.configure( text=f"""Threshold {spinbox_value}""") # QUEUE_SPINBOX is really not necessary? # update spinbox_value to QUEUE_SPINBOX # print('__file__: ', __file__, f'placing spinbox [{spinbox_value}] in QUEUE_SPINBOX') logger.debug( "spinbox_value [%s] in QUEUE_SPINBOX", spinbox_value, ) # QUEUE_SPINBOX.put(spinbox_value) try: self.spinbox_value = float(spinbox_value) except Exception as exc: logger.error( " self.spinbox_value = float(spinbox_value) exc: %s", exc) self.spinbox_value = 0.64 logger.debug( "self.spinbox_value [%s] in QUEUE_SPINBOX", self.spinbox_value, ) queue1_put(QUEUE_SPINBOX, spinbox_value)
def reset_command(self, event=None): """ reset_command. self is aligner """ logger.debug("reset_command") # sys.stdout.flush() res = messagebox.askyesnocancel(f"Reset everythin?", f"This will reset everything. Continue?", default="no", icon="question") if not res: return None len_ = 5 _ = zip(range(1, 1 + len_), range(1 + len_, 1 + len_ + len_), [""] * len_) df = DataFrame(_, columns=["text1", "text2", "merit"]) self.Table.model.df = df _ = extract_rows(self.Table.model.df, self.Table.row_clicked) SIG_PAD.send(data=_) self.Table.show() self.Table.redraw() for elm in ( QUEUE_T1, QUEUE_T2, QUEUE_P1, QUEUE_P2, QUEUE_PM, QUEUE_S1, QUEUE_S2, QUEUE_SM, QUEUE_PA, QUEUE_SA, QUEUE_PS, ): queue1_put(elm, "") self.filename1 = "" self.filename2 = "" self.text1 = "" self.text2 = "" self.paras1 = "" self.paras2 = "" self.paras_merit = "" self.sents1 = "" self.sents2 = "" self.sents_merit = "" self.paligned = False self.saligned = False logger.debug("reset df to: %s", df)
def palign_command(self, event=None): """ palign_command. """ logger.debug("palign_command") try: _ = QUEUE_PS.get_nowait() except Empty: _ = "" queue1_put(QUEUE_PS, _) # restore # QUEUE_PS0 no longer used, paligner disabled after 1st use # queue1_put(QUEUE_PS0, _) # pervious state of QUEUE_PS QUEUE_PS0.append(_) # pervious state of QUEUE_PS # mark QUEUE_PS as "p" queue1_put(QUEUE_PS, "p") top = self.top # top = None self.pbtoplevel = tk.Toplevel(top) # window = tk.Toplevel(top) # window = tk.Toplevel(self) does not work # refer to open_settings_window.py myprogressbar_ui_support.set_Tk_var() # QUEUE_SPINBOX.put('*') # pbar = Mypbar(window) pbar = Mypbar(self.pbtoplevel) # pbar = Mypbar(self) # disbale cancel butt until start is clicked # TButton 1: Start, 2: Cancel,3: Back pbar.TButton1.config(state=tk.NORMAL) pbar.TButton3.config(state=tk.NORMAL) pbar.TButton2.config(state=tk.DISABLED) logger.debug(" disable PAlign ") self.sub_menu1.entryconfig("PAlign", state="disabled") # logger.debug(" disable Pad ") # self.Pad.config(state="disabled") # cant do this with Pad (Frame) # window.focus_force() self.pbtoplevel.focus_force() # window.grab_set() logger.debug(" palign_command exit ") return None
def salign_command(self, event=None): """ salign_command. """ logger.info("salign_command") try: _ = QUEUE_PS.get_nowait() except Empty: _ = "" queue1_put(QUEUE_PS, _) # restore # send model.df to QUEUE_DF logger.debug("sending Table.model.df to QUEUE_DF") QUEUE_DF.append(self.Table.model.df) # QUEUE_PS0 pervious state of QUEUE_PS QUEUE_PS0.append(_) # pervious state of QUEUE_PS # this is only for selecting check_thread_update queue1_put(QUEUE_PS, "s") top = self.top # top = None self.pbtoplevel = tk.Toplevel(top) # window = tk.Toplevel(top) # window = tk.Toplevel(self) does not work # refer to open_settings_window.py myprogressbar_ui_support.set_Tk_var() # QUEUE_SPINBOX.put('*') # pbar = Mypbar(self) # pbar = Mypbar(window) pbar = Mypbar(self.pbtoplevel) # disable Spinbox pbar.Spinbox1.config(state=tk.DISABLED) # disbale cancel butt until start is clicked # TButton1: Start, 2: Cancel,3: Back pbar.TButton2.config(state=tk.DISABLED) # window.focus_force() # window.grab_set() self.pbtoplevel.grab_set() logger.debug(" salign_command exit ") return None
def cancel_command(self): """ cancel align and destroy pbar. """ from time import sleep logger.debug("self.cancel_command") logger.debug("QUEUE_S.put(True, block=0") # QUEUE_S.put(True, block=False) queue1_put(QUEUE_S, True) sleep(0.8) # wait for thread to quit # for salign_command try: flag = QUEUE_PS.get_nowait() queue1_put(QUEUE_PS, flag) except Empty: flag = "" if flag in ["s"]: # activated from salign_command logger.debug(""" pbar-s send blinker.signal to aligner slot: {"PAlign": True}""") SIG_ALIGNER.send( "pbar-s", **{ "PAlign": False, "SAlign": True, "pbtoplevel": False, # pbar grab_release, permits editing Pad }) return None # for palign_command logger.debug( """ pbar-p send blinker.signal to aligner slot: {"PAlign": True}""" ) SIG_ALIGNER.send( "pbar-p", **{ "PAlign": True, # "SAlign": True, "pbtoplevel": False, # pbar grab_release, permits editing Pad })
def savetmx_command(self, event=None) -> None: """ savetmx_command. self is aligner self.Table.model.df: DataFrame of interest self.filename1, self.filename2 """ # check QUEUE_PA QUEUE_SA try: self.paligned = QUEUE_PA.get_nowait() queue1_put(QUEUE_PA, self.paligned) except Empty: self.paligned = False try: self.saligned = QUEUE_SA.get_nowait() queue1_put(QUEUE_SA, self.saligned) except Empty: self.saligned = False if QUEUE_P1.qsize(): self.paras1 = QUEUE_P1.get_nowait() queue1_put(QUEUE_P1, self.paras1) if QUEUE_P2.qsize(): self.paras2 = QUEUE_P2.get_nowait() queue1_put(QUEUE_P2, self.paras2) if QUEUE_PM.qsize(): self.paras_merit = QUEUE_PM.get_nowait() queue1_put(QUEUE_PM, self.paras_merit) if QUEUE_S1.qsize(): self.sents1 = QUEUE_S1.get_nowait() queue1_put(QUEUE_S1, self.sents1) if QUEUE_S2.qsize(): self.sents2 = QUEUE_S2.get_nowait() queue1_put(QUEUE_S2, self.sents2) if QUEUE_SM.qsize(): self.sents_merit = QUEUE_SM.get_nowait() queue1_put(QUEUE_SM, self.sents_merit) filename1 = self.filename1 filename2 = self.filename2 if not (filename1 and filename2): logger.info(" filename1: %s, filename2: %s not loaded", filename1, filename2) # message = f"filename1: *{filename1}*, filename2: *{filename2}* not loaded" messagebox.showwarning( title="Not ready", message= f"filename1: *{filename1}*, filename2: *{filename2}* not loaded") return None logger.debug("file1: %s", filename1) logger.debug("file2: %s", filename2) prefix = common_prefix([ Path(filename1).stem, Path(filename2).stem, ]) tmxfile_p = gen_filename(f"{prefix}aligned-p.tmx") tmxfile_s = gen_filename(f"{prefix}aligned-s.tmx") path_ = Path(filename1).parent tmxfile_p = f"{path_ / tmxfile_p}" tmxfile_s = f"{path_ / tmxfile_s}" msg = "\n" logger.debug(" self.saligned %s, self.paligned %s", self.saligned, self.paligned) logger.debug(" self.paras1: %s, self.paras2: %s", self.paras1, self.paras2) if self.paligned: tmx = lists_to_tmx(self.paras1, self.paras2) Path(tmxfile_p).write_text(tmx, "utf8") logger.info(" Aligned paras saved to %s", tmxfile_p) msg += " Aligned paras saved to %s\n" % tmxfile_p # logger.debug(" self.sents1[:5]: %s, self.sents2[:5]: %s", self.sents1[:5], self.sents2[:5]) if self.saligned: df_ = self.Table.model.df df_.replace("", np.nan, inplace=True) df_.dropna(axis=0, inplace=True) # tmx = lists_to_tmx(self.sents1, self.sents2) try: tmx = lists_to_tmx(list(df_["text1"]), list(df_["text2"])) except Exception as exc: logger.error( """ tmx = lists_to_tmx(list(df_['text1']), list(df_['text2'])) exc: %s""", exc) tmx = str(exc) Path(tmxfile_s).write_text(tmx, "utf8") # df_.to_csv(csvfile_s, index=False, header=False, encoding="gbk") logger.info(" Aligned sents saved to %s", tmxfile_s) msg += " Aligned sents saved to %s" % tmxfile_s msg = msg.strip() if msg: messagebox.showinfo(title="File(s) saved", message=msg) logger.debug("tmxfile: %s, %s", tmxfile_p, tmxfile_s) else: message = "Do some work first..." messagebox.showwarning(title="Nothing to save, yet", message=message) logger.info("savetmx_command")
def paste2_command(self, event=None): # pylint: disable=unused-argument """ paste2_command. """ # from load_paras import load_paras logger.debug("<paste2_command>") # text2 = pyperclip.copy().strip() try: win = tk.Tk() win.withdraw() text2 = win.clipboard_get().strip() except Exception as exc: logger.error(" text2 = tk.Tk().clipboard_get() exc: %s", exc) text2 = str(exc) if not text2.strip(): messagebox.showwarning(" Nothing in the clipboard ", "Copy something to the system clipbaord first and try again.") return None file = "clipboard2.txt" # convert to para list # text2 = re.split(r"[\r\n]+", text2) text2 = [elm for elm in text2.splitlines() if elm.strip()] self.text2 = text2[:] logger.debug(" from clipboard self.text2[:3]: %s", self.text2[:3]) # values = self.text2.split('\n') values = self.text2 df = self.Table.model.df df.columns = ["text1", "text2", "merit"] df = insert_column(values, df, 1) # reset merit column to all "" df = insert_column([""] * df.shape[0], df, 2) # # cp_load_text2 self.Table.model.df = df # reset merit # self.Table.model.df.merit = "" # logger.debug(self.Table.model.df) logger.debug("self.Table.model.df[:3]: %s", self.Table.model.df[:3]) # send self.Table.model.df[:3] to PAD # SIG_TABLE.send(data=self.Table.model.df[:3]) # data = extract_rows(self.model.df, self.row_clicked) # pretend row 0 clicked # data = extract_rows(self.Table.model.df, 0) data = extract_rows(self.Table.model.df, self.Table.row_clicked) # logger.debug("data sent to SIG_TABLE.send(data=data): %s", data) logger.debug("data sent to SIG_TABLE.send(data=data): %s", data) # SIG_TABLE.send(data=data) # update pad via slot_pad SIG_PAD.send(data=data) self.Table.show() self.Table.redraw() self.filename2 = file logger.debug(" setting filename2 *%s* and QUEUE_T2 self.text2[:3] %s", self.filename2, self.text2[:3]) queue1_put(QUEUE_T2, self.text2) queue1_put(QUEUE_P2, self.text2) if self.text1 and self.text2: self.sub_menu1.entryconfig("PAlign", state="normal") logger.debug(""" enabling PAlign: logger.debug(" enabling PAlign ") """)
def paste1_command(self, file12="file1", event=None): # pylint: disable=unused-argument """ paste1. """ logger.debug("paste1_command") # text2 = pyperclip.copy().strip() # text1 = pyperclip.copy().strip() try: win = tk.Tk() win.withdraw() text1 = win.clipboard_get().strip() except Exception as exc: logger.error(" text1 = tk.Tk().clipboard_get() exc: %s", exc) text1 = str(exc) if not text1.strip(): messagebox.showwarning( " Nothing in the clipboard ", "Copy something to the system clipbaord first and try again.") return None file = "clipboard1.txt" # convert to para list # text1 = re.split(r"[\r\n]+", text1) text1 = [elm for elm in text1.splitlines() if elm.strip()] self.text1 = text1[:] logger.debug("self.text1[:3]: %s", self.text1[:3]) # detect, ask and separate # text1 = "\n".join(self.text1) s_or_d = single_or_dual(text1) if len(s_or_d) == 2: # dualtext res = messagebox.askyesnocancel( f"Dual-language file or not", f"Tkaligner thinks this is a dual-language {s_or_d} file. Do you want to treat it as such? (If you press Yes, it will take about two minutes to process the file.)", default="yes", icon="question") logger.debug(" res = messagebox.askyesnocancel: res %s", res) if res is None: return if res: # handle bilingual text # bumblebee_aligner st-bee-aligner.py # p_list = text_to_plist(src_file, langs=s_or_d) # may need an indeterminate progressbar # p_list = text_to_plist(text1, langs=s_or_d) thr = Thread( target=text_to_plist, args=(text1, ), # kwargs=dict(langs=s_or_d), kwargs={"langs": s_or_d}, # target=longtime_job, # kwargs={"counter": 16}, # name='job_thr', ) thr.stop = False # type: ignore # prepare for check_thread_update1 # to set self.filename1/2 when successfully run thr.filename1 = file # type: ignore thr.filename2 = file # type: ignore thr.start() # refer to paligner.py self is Aligner rt = self.top # top = Pbar(rt) # this does not work top = tk.Toplevel(rt) pbar = Pbar(top) pbar.TProgressbar1.start(50) # check_thread_update1(thr, top, pbar) # check_thread_update1(thr, pbar) check_thread_update1(self, thr, pbar) # disable Pad editing blinker.signal("aligner").send( "paste1_comman", pbtoplevel="True") # SIG_ALIGNER.send return None else: # user opts for single-lang # left: self.text1 part values = self.text1 df = self.Table.model.df df.columns = ["text1", "text2", "merit"] df = insert_column(values, df, 0) # reset merit column to all "" df = insert_column([""] * df.shape[0], df, 2) # cp_load_text1 self.Table.model.df = df # left: self.text1 part # self.filename1 = file else: # single-lang, normal # left: self.text1 part values = self.text1 df = self.Table.model.df df.columns = ["text1", "text2", "merit"] df = insert_column(values, df, 0) # reset merit column # self.Table.model.df.merit = "" df = insert_column([""] * df.shape[0], df, 2) # cp_load_text1 self.Table.model.df = df # logger.debug(self.Table.model.df) # data = extract_rows(self.Table.model.df, 0) data = extract_rows(self.Table.model.df, self.Table.row_clicked) logger.debug("data sent to SIG_PAD.send(data=data): %s", data) # SIG_TABLE.send(data=data) SIG_PAD.send(data=data) self.Table.show() self.Table.redraw() self.filename1 = file # logger.debug(" setting filename1 and QUEUE_T1") # logger.debug(" setting filename1 *%s* and QUEUE_T2", self.filename1) logger.debug(" setting filename1 *%s* and QUEUE_T1 self.text1[:3] %s", self.filename1, self.text1[:3]) queue1_put(QUEUE_T1, self.text1) queue1_put(QUEUE_P1, self.text1) if self.text1 and self.text2: self.sub_menu1.entryconfig("PAlign", state="normal") logger.debug( """ enabling PAlign: logger.debug(" enabling PAlign ") """)
def longtime_job(*args, **kwargs): """ longtime job. QUEUE.put_nowait(percentage completed): numb in % QUEUE_C.put_nowait( label ): f"elm/tot" .put_nowait replaced by queue1_put: Queue(1), only keeps the most updated content exit on QUEUE_S (True) """ longtime_job.res = None logger.debug("<longtime_job> entry, kwargs: %s", kwargs) # reset QUEUE, QUEUE_S, QUEUE_C # QUEUE.put(0, block=False) # QUEUE_C.put(0, block=False) queue1_put(QUEUE, 0) queue1_put(QUEUE_C, 0) # run in a thread thr, able to fetch thread related info c_thr = currentThread() logger.debug(" c_th.ident: %s, c_th.name: %s", c_thr.ident, c_thr.name) # c_thr.stop = False # not used, deleted # c_thr.value = 0 # emitate worker # pbar start butt/bind to start_command: # run check_thread_update, thread( of longtime_job).start() if kwargs.get("counter"): try: counter = int(kwargs.get("counter")) except Exception as exc: logger.error("exc: %s", exc) counter = 10 else: counter = 10 for elm in range(counter): logger.debug(f"{elm}/{counter}") # check QUEUE_S size 1 queue_s = None if not QUEUE_S.qsize() else QUEUE_S.get_nowait() if queue_s: # QUEUE_S True, quit working break # sleep(0.5) # pretending doing work sleep(0.2) # pretending doing work # sleep(1.0) # pretending doing work # step = 1 / counter * 100 # c_value out of 100 completed c_value = (elm + 1) / counter * 100. # send to respective QUEUEs # QUEUE.put(c_value, block=False) # QUEUE_C.put(f"{elm}/{counter}", block=False) queue1_put(QUEUE, c_value) queue1_put(QUEUE_C, f"{elm + 1}/{counter}") # for ... break ... else else: # if break does not occur/loop completed logger.debug("<<longtime_job>> exit") # normal exit, reset pbar c_value = 0 # reset pbar longtime_job.res = "normal return result" c_thr.res = "normal return result" df = DataFrame(zip([1, 1, 1], [0, 0, 0], [''] * 3), columns=['text1', 'text2', 'merit']) # logger.info("SIG_PAD.send(\"job\", df=df: %s,)", df) SIG_TABLE.send("job", df=df) # SIG_PAD.send("job", df=df) return None # normal function return # break does occur c_thr.res = "" logger.debug("breaking..., reset progressbar") c_value = 0 # reset pbar # QUEUE.put(0, block=False) # QUEUE_C.put(f"{0}/{counter}", block=False) queue1_put(QUEUE, 0) queue1_put(QUEUE_C, f"{0}/{counter}")
def check_thread_update(self, thr): """ check thread thr and update pbar via QUEUE. called in myprogressbar_ui called by paligner/saligner self is pbar in palign_command: pbar = myprogressbar_ui.Mypbar(window) [window = tk.Toplevel(top)] / top = self.top / self(aligner) """ pbar = self if thr.is_alive(): # logger.debug("+++ check_threa_update %s ++alive++ ", thr.name) # pbar.TProgressbar1.step() # pbar.TProgressbar1['value'] = thr.value # this does not update for some weird reason # c_value = pbar.TProgressbar1['value'] # c_value = pbar.TProgressbar1['value'] # set pbar: # pbar.TProgressbar1['value'] = number def update_status(): """ update running label. need to reuse this when the thread is terminated """ old_value = pbar.TProgressbar1["value"] if QUEUE.qsize(): # pbar queue c_value = QUEUE.get_nowait() logger.debug("**== check_thread_update QUEUE. c_value: %.2f", c_value) step = c_value - old_value pbar.TProgressbar1.step(step) # counter text queue if QUEUE_C.qsize(): text = QUEUE_C.get_nowait() logger.debug("**== check_thread_update QUEUE_C text: %s", text) # myprogressbar_ui_support.pbarvar.set(text) myprogressbar_ui_support.statustext.set(text) # pbar.TLabel1.delete('0.0', 'end') # pbar.TLabel1.insert('0.0', text) update_status() # resursive # pbar.TProgressbar1.after(500, lambda: check_thread_update(thr, pbar)) pbar.TProgressbar1.after(500, lambda: check_thread_update(pbar, thr)) else: # not thr.is_alive(), finished aligning # update_status() logger.debug("*** %s not alive", thr.name) logger.debug( # "value(pbar): %s:thr.value %s", pbar.TProgressbar1["value"], thr.value # thr.value removed, TProgressbar1 fetches value from QUEUE/QUEUE_C "value(pbar): %s", pbar.TProgressbar1["value"]) # extra update after thread exited # c_value = pbar.TProgressbar1["value"] # step = thr.value - c_value # pbar.TProgressbar1.step(step - 0.1) # pbar.TProgressbar1.update() old_value = pbar.TProgressbar1["value"] if QUEUE.qsize(): # pbar queue c_value = QUEUE.get_nowait() logger.debug("**== check_thread_update QUEUE. c_value: %.2f", c_value) step = c_value - old_value pbar.TProgressbar1.step(step - 0.1) # update running label/statustext if QUEUE_C.qsize(): text = QUEUE_C.get_nowait() logger.debug("**== check_thread_update QUEUE_C text: %s", text) # myprogressbar_ui_support.pbarvar.set(text) myprogressbar_ui_support.statustext.set(text) logger.debug(" Restore buttons 1 2 3 states") # pbar(self) TButton1: Start, 2: Cancel,3: Back pbar.TButton1.config(state=tk.NORMAL) pbar.TButton2.config(state=tk.DISABLED) pbar.TButton3.config(state=tk.NORMAL) # stop the indeterminate progressbar pbar.TProgressbar1.stop() pbar.TProgressbar1['value'] = 1 # pbar.TProgressbar1.destroy() # dose not work try: flag = QUEUE_PS.get_nowait() queue1_put(QUEUE_PS, flag) except Empty: flag = "" logger.debug(" flag = QUEUE_PS.get_nowait(): %s ", flag) # ######### SENTS ########### # set QUEUE_SA self.saligned if flag in ["s"]: # activated from salign_command # update Table and Pad from bee_aligner.plist_to_slist thread # in myprogressbar_ui/start_command try: s_list = thr.flist # thr is c_th in plist_to_slist except Exception as exc: logger.error( "s_list = thr.flist exc: %s, maybe thread has not run well or has been attached a different result", exc) return None logger.debug("s_list[:5]: %s", s_list[:5]) logger.debug( """ SIG_TABLE.send("check_thread_update", df=s_list) """) SIG_TABLE.send("check_thread_update", df=s_list) # set QUEUE_SA self.saligned queue1_put(QUEUE_SA, True) # set QUEUE_S1, QUEUE_S2 QUEUE_SM df = DataFrame(s_list) queue1_put(QUEUE_S1, df[0]) queue1_put(QUEUE_S2, df[1]) queue1_put(QUEUE_SM, df[2]) queue1_put(QUEUE_PS, 's') logger.info("Sent aligning completed.") logger.debug( """messagebox.showinfo(" Sent aligning completed!", "You can edit the upper table...""" ) messagebox.showinfo( " Sent aligning completed!", "You can edit the upper table manually and press Start to realign or press Back" ) signal = { "PAlign": False, "SAlign": True, "pbtoplevel": False, # pbar grab_release } logger.debug( """pbar-s send blinker.signal to aligner slot: %s """, signal) SIG_ALIGNER.send("check_thread_update1", **signal) logger.debug(" <check_thread_update> exit") return None # ######### PARAS ########### # set QUEUE_PA self.paligned # update Table and Pad from bee_aligner.bee_aligner thread # in myprogressbar_ui/start_command logger.debug( """messagebox.showinfo(" Para aligning completed!", "You can adjust...""" ) messagebox.showinfo( " Paras aligning completed!", "You can adjust the threshold and press Start realign or press Back and edit the upper table manually." ) para_list = thr.para_list # thr is c_th in bee_aligner SIG_TABLE.send("check_thread_update", df=para_list) queue1_put(QUEUE_PA, True) # set QUEUE_P1, QUEUE_P2 QUEUE_PM df = DataFrame(para_list) # logger.debug(" DataFrame(p_list).head(3): %s", df.head(3)) self.paras1 = df[0] self.paras2 = df[1] self.paras_merit = df[2] # self.text1 = "\n".join(self.paras1) # self.text2 = "\n".join(self.paras2) queue1_put(QUEUE_P1, self.paras1) queue1_put(QUEUE_P2, self.paras2) queue1_put(QUEUE_PM, self.paras_merit) # QUEUE_T1/2 only needed for Ctrl-P for the first time # queue1_put(QUEUE_T1, self.text1) # queue1_put(QUEUE_T2, self.text2) self.paligned = True queue1_put(QUEUE_PA, True) # QUEUE_PS also for another purpose: # controls branching in check_thread_update # self.Table.model.df currently is paras1/2/_merit queue1_put(QUEUE_PS, 'p') # update QUEUE_PS # cp_p logger.info( "update: self.paras1/2/_merit, Q_P1/2/M self.text1/2, Q_T1/2 self.paligned/Q_PA " ) logger.info("paras aligning completed.") logger.debug(" check_thread_update-p exit") # enable SAlign in pbar.back_command to avoid confusion signal = {"pbtoplevel": True} logger.debug("send blinker.signal to aligner slot, signal: %s", signal) SIG_ALIGNER.send("check_thread_update", **signal)
def __init__(self, top=None): super().__init__() '''This class configures and populates the toplevel window. top is the toplevel containing window.''' # atexit.register(quit_command, self) self.top = top self.pbtoplevel: Optional[tk.Toplevel] = None iconpath = Path(__file__).parent / "align.ico" top.iconbitmap(str(iconpath)) self.spinbox = '' # QUEUE_SPINBOX.put('*') queue1_put(QUEUE_SPINBOX, '*') def handle_signal(sender, **kw): self.slot(sender, **kw) self.handle_signal = handle_signal # important, not for nothing SIG_ALIGNER.connect(handle_signal) # in effect SIG_ALIGNER.connect(self.slot) # aux props self.filename1 = "" self.filename2 = "" self.text1 = "" # type: Union[str, List[str]] self.text2 = "" # type: Union[str, List[str]] self.paras1 = "" self.paras2 = "" self.paras_merit = "" self.sents1 = "" self.sents2 = "" self.sents_merit = "" self.paligned = False self.saligned = False _bgcolor = '#d9d9d9' # X11 color: 'gray85' _fgcolor = '#000000' # X11 color: 'black' _compcolor = '#d9d9d9' # X11 color: 'gray85' _ana1color = '#d9d9d9' # X11 color: 'gray85' _ana2color = '#ececec' # Closest X11 color: 'gray92' font9 = "-family {Segoe UI} -size 9" top.geometry("980x625+100+25") top.minsize(120, 1) top.maxsize(1284, 781) top.resizable(1, 1) top.title("Tkaligner") top.configure(background="#d9d9d9") top.configure(highlightbackground="#d9d9d9") top.configure(highlightcolor="black") self.FramePad = tk.Frame(top) self.FramePad.place(relx=0.0, rely=0.0, relheight=0.5, relwidth=1.0) self.FramePad.configure(relief='groove') self.FramePad.configure(borderwidth="2") self.FramePad.configure(relief="groove") self.FramePad.configure(background="#d9d9d9") self.FramePad.configure(highlightbackground="#d9d9d9") self.FramePad.configure(highlightcolor="black") # self.Pad = aligner_ui_support.Custom(self.FramePad) self.Pad = MyPad(self.FramePad) self.Pad.c01.configure(wrap="word") self.Pad.c02.configure(wrap="word") self.Pad.c11.configure(wrap="word") self.Pad.c12.configure(wrap="word") self.Pad.c21.configure(wrap="word") self.Pad.c22.configure(wrap="word") self.Pad.place(relx=0.0, rely=0.0, relheight=1.0, relwidth=1.0) self.FrameTable = tk.Frame(top) self.FrameTable.place(relx=0.0, rely=0.5, relheight=0.5, relwidth=1.0) self.FrameTable.configure(relief='groove') self.FrameTable.configure(borderwidth="2") self.FrameTable.configure(relief="groove") self.FrameTable.configure(background="#d9d9d9") self.FrameTable.configure(highlightbackground="#d9d9d9") self.FrameTable.configure(highlightcolor="black") # self.Table = aligner_ui_support.Custom(self.FrameTable) self.Table = MyTable(self.FrameTable) self.Table.place(relx=0.0, rely=0.0, relheight=1.0, relwidth=1.0) self.Table.show() self.menubar = tk.Menu(top, font=font9, bg=_bgcolor, fg=_fgcolor) top.configure(menu=self.menubar) self.sub_menu = tk.Menu(top, tearoff=0) self.menubar.add_cascade(menu=self.sub_menu, activebackground="#ececec", activeforeground="#000000", background="#d9d9d9", font="TkDefaultFont", foreground="#000000", label="File") self.sub_menu.add_command( activebackground="#ececec", activeforeground="#000000", accelerator="Ctrl+O", background="#d9d9d9", # command=aligner_ui_support.self.open1_command, # command=self.open1_command, command=lambda: open1_command(self), font="TkDefaultFont", foreground="#000000", label="Open1", underline=0) self.sub_menu.add_command( activebackground="#ececec", activeforeground="#000000", accelerator="Ctrl+N", background="#d9d9d9", # command=aligner_ui_support.self.open2_command, # command=self.open2_command, command=lambda: open2_command(self), font="TkDefaultFont", foreground="#000000", label="Open2", underline=1) self.sub_menu.add_command( activebackground="#ececec", activeforeground="#000000", # accelerator="Ctrl+O", background="#d9d9d9", # command=aligner_ui_support.self.open1_command, # command=self.open1_command, command=lambda: paste1_command(self), font="TkDefaultFont", foreground="#000000", label="Paste1", underline=0) self.sub_menu.add_command( activebackground="#ececec", activeforeground="#000000", # accelerator="Ctrl+N", background="#d9d9d9", # command=aligner_ui_support.self.open2_command, # command=self.open2_command, command=lambda: paste2_command(self), font="TkDefaultFont", foreground="#000000", label="Paste2", underline=1) self.sub_menu.add_separator(background="#d9d9d9") self.sub_menu.add_command( activebackground="#ececec", activeforeground="#000000", # accelerator="Ctrl+C", background="#d9d9d9", # command=aligner_ui_support.self.savecsv_command, # command=self.savecsv_command, command=lambda: savecsv_command(self), font="TkDefaultFont", foreground="#000000", label="SaveCsv", underline=4) self.sub_menu.add_command( activebackground="#ececec", activeforeground="#000000", accelerator="Ctrl+T", background="#d9d9d9", # command=aligner_ui_support.self.savetmx_command, # command=self.savetmx_command, command=lambda: savetmx_command(self), font="TkDefaultFont", foreground="#000000", label="SaveTMX", underline=5) self.sub_menu.add_command( activebackground="#ececec", activeforeground="#000000", # accelerator="Ctrl+X", accelerator="Ctrl+L", background="#d9d9d9", command=lambda: savexlsx_command(self), foreground="#000000", label="SaveXlsx", underline=7) self.sub_menu.add_separator(background="#d9d9d9") self.sub_menu.add_command( activebackground="#ececec", activeforeground="#000000", accelerator="Ctrl-Q", background="#d9d9d9", # command=self.quit_command, command=lambda: quit_command(self), font="TkDefaultFont", foreground="#000000", label="Quit", underline=0) self.sub_menu1 = tk.Menu(top, tearoff=0) self.menubar.add_cascade(menu=self.sub_menu1, activebackground="#ececec", activeforeground="#000000", background="#d9d9d9", font="TkDefaultFont", foreground="#000000", label="Edit") self.sub_menu1.add_command( activebackground="#ececec", activeforeground="#000000", accelerator="Ctrl+P", background="#d9d9d9", # command=self.palign_command, command=lambda: palign_command(self), font="TkDefaultFont", foreground="#000000", label="PAlign", underline=0) self.sub_menu1.add_command( activebackground="#ececec", activeforeground="#000000", accelerator="Ctrl+S", background="#d9d9d9", # command=self.salign_command, command=lambda: salign_command(self), font="TkDefaultFont", foreground="#000000", label="SAlign", underline=0) self.sub_menu1.add_command( activebackground="#ececec", activeforeground="#000000", accelerator="Ctrl+R", background="#d9d9d9", # command=self.reset_command, command=lambda: reset_command(self), font="TkDefaultFont", foreground="#000000", label="Reset", underline=0) self.sub_menu12 = tk.Menu(top, tearoff=0) self.menubar.add_cascade(menu=self.sub_menu12, activebackground="#ececec", activeforeground="#000000", background="#d9d9d9", font="TkDefaultFont", foreground="#000000", label="Help") self.sub_menu12.add_command(activebackground="#ececec", activeforeground="#000000", accelerator="Ctrl+H", background="#d9d9d9", command=on_howto, font="TkDefaultFont", foreground="#000000", label="Howto", underline=0) self.sub_menu12.add_command(activebackground="#ececec", activeforeground="#000000", accelerator="Ctrl-I", background="#d9d9d9", command=on_about, font="TkDefaultFont", foreground="#000000", label="About", underline=0) self.sub_menu.bind_all('<Control-Key-h>', lambda e: on_howto(e)) self.sub_menu.bind_all('<Control-Key-i>', lambda e: on_about(e)) # self.sub_menu.bind_all('<Control-Key-o>',lambda e: self.open1_command(e)) self.sub_menu.bind_all('<Control-Key-o>', lambda e: open1_command(self, event=e)) # self.sub_menu.bind_all('<Control-Key-p>',lambda e: self.open2_command(e)) self.sub_menu.bind_all('<Control-Key-n>', lambda e: open2_command(self, event=e)) # self.sub_menu.bind_all('<Control-Key-t>',lambda e: self.savecsv_command(e)) # self.sub_menu.bind_all('<Control-Key-c>',lambda e: savecsv_command(self, event=e)) # self.sub_menu.bind_all('<Control-Key-m>',lambda e: self.savetmx_command(e)) self.sub_menu.bind_all('<Control-Key-m>', lambda e: savetmx_command(self, event=e)) # self.sub_menu.bind_all('<Control-Key-x>',lambda e: savexlsx_command(self, event=e)) self.sub_menu.bind_all('<Control-Key-l>', lambda e: savexlsx_command(self, event=e)) self.sub_menu.bind_all('<Control-Key-q>', lambda e: quit_command(self, event=e)) self.sub_menu.bind_all('<Control-Key-p>', lambda e: palign_command(self, event=e)) self.sub_menu.bind_all('<Control-Key-s>', lambda e: salign_command(self, event=e)) self.sub_menu.bind_all('<Control-Key-r>', lambda e: reset_command(self, event=e)) # some menu itmes initially disabled self.sub_menu1.entryconfig("PAlign", state="disabled") self.sub_menu1.entryconfig("SAlign", state="disabled")
def savecsv_command(self, event=None) -> None: """ savecsv_command. self is aligner self.Table.model.df: DataFrame of interest self.filename1, self.filename2 """ # check QUEUE_PA QUEUE_SA try: self.paligned = QUEUE_PA.get_nowait() queue1_put(QUEUE_PA, self.paligned) except Empty: self.paligned = False try: self.saligned = QUEUE_SA.get_nowait() queue1_put(QUEUE_SA, self.saligned) except Empty: self.saligned = False if QUEUE_P1.qsize(): self.paras1 = QUEUE_P1.get_nowait() queue1_put(QUEUE_P1, self.paras1) if QUEUE_P2.qsize(): self.paras2 = QUEUE_P2.get_nowait() queue1_put(QUEUE_P2, self.paras2) if QUEUE_PM.qsize(): self.paras_merit = QUEUE_PM.get_nowait() queue1_put(QUEUE_PM, self.paras_merit) if QUEUE_S1.qsize(): self.sents1 = QUEUE_S1.get_nowait() queue1_put(QUEUE_S1, self.sents1) if QUEUE_S2.qsize(): self.sents2 = QUEUE_S2.get_nowait() queue1_put(QUEUE_S2, self.sents2) if QUEUE_SM.qsize(): self.sents_merit = QUEUE_SM.get_nowait() queue1_put(QUEUE_SM, self.sents_merit) filename1 = self.filename1 filename2 = self.filename2 if not (filename1 and filename2): logger.info(" filename1: %s, filename2: %s not loaded", filename1, filename2) # message = f"filename1: *{filename1}*, filename2: *{filename2}* not loaded" messagebox.showwarning( title="Not ready", message= f"filename1: *{filename1}*, filename2: *{filename2}* not loaded") return None logger.debug("file1: %s", filename1) logger.debug("file2: %s", filename2) prefix = common_prefix([ Path(filename1).stem, Path(filename2).stem, ]) csvfile_p = gen_filename(f"{prefix}aligned-p.csv") csvfile_s = gen_filename(f"{prefix}aligned-s.csv") path_ = Path(filename1).parent csvfile_p = f"{path_ / csvfile_p}" csvfile_s = f"{path_ / csvfile_s}" msg = "\n" logger.debug(" self.saligned %s, self.paligned %s", self.saligned, self.paligned) logger.debug(" self.paras1: %s, self.paras2: %s", self.paras1, self.paras2) if self.paligned: df_ = DataFrame({ "text1": self.paras1, "text2": self.paras2, "merit": self.paras_merit }) try: df_.to_csv(csvfile_p, index=False, header=False, encoding="gbk") logger.info(" Aligned paras saved to %s", csvfile_p) msg += " Aligned paras saved to %s\n" % csvfile_p except UnicodeEncodeError: try: df_.to_csv(csvfile_p, index=False, header=False, encoding="utf-8") logger.info(" Aligned paras saved to %s", csvfile_p) msg += " Aligned paras saved to %s\n" % csvfile_p except Exception as exc: logger.error(" df_.to_csv exc: %s", exc) msg += " Aligned paras save exc: %s\n" % exc # logger.debug(" self.sents1[:5]: %s, self.sents2[:5]: %s", self.sents1[:5], self.sents2[:5]) if self.saligned: _ = """ df_ = DataFrame({ "text1": self.sents1, "text2": self.sents2, "merit": self.sents_merit }) # """ df_ = self.Table.model.df # remove all empty rows # df0.replace("", np.nan).dropna(axis=0) # df_ = df_.replace("", np.nan).dropna(axis=0) df_.replace("", np.nan, inplace=True) df_.dropna(axis=0, inplace=True) try: df_.to_csv(csvfile_s, index=False, header=False, encoding="gbk") logger.info(" Aligned sents saved to %s", csvfile_s) msg += " Aligned sents saved to %s" % csvfile_s except Exception as exc: try: df_.to_csv(csvfile_s, index=False, header=False) logger.info(" Aligned sents saved to %s", csvfile_s) msg += " Aligned sents saved to %s" % csvfile_s except Exception as exc: logger.error(" df_.to_csv exc: %s", exc) msg += " Saving csv exc: %s " % exc msg = msg.strip() if msg: messagebox.showinfo(title="File(s) saved", message=msg) logger.debug("csvfile: %s, %s", csvfile_p, csvfile_s) else: message = "Do some work first..." messagebox.showwarning(title="Nothing to save, yet", message=message) logger.info("savecsv_command")
def open1_command(self, file12="file1", event=None): # pylint: disable=unused-argument """ open1. """ logger.debug("open1_command") if file12 in ["file1"]: # file1 or file2, not implemented yet ... file = filedialog.askopenfilename( title="Select a file", filetypes=( ("text files", "*.txt"), # ("pdf files", "*.pdf"), # ("docx files", "*.docx"), ("all files", "*.*"), ), ) if file is not None: # self.text.delete('1.0', END) # self.text1 = file.read() try: try: text1, _ = load_paras(file) except ValueError: text1 = load_paras(file) except Exception as exc: logger.error("exc: %s", exc) text1 = [] if not " ".join(text1).strip(): messagebox.showwarning(" Empty text", "Nothing loaded, we just exit. ") return None self.text1 = text1[:] logger.debug("self.text1[:3]: %s", self.text1[:3]) # file.close() # detect, ask and separate text1 = "\n".join(self.text1) s_or_d = single_or_dual(text1) # self.text2 = "" if len(s_or_d) == 2: # dualtext res = messagebox.askyesnocancel( f"Dual-language file or not", f"Tkaligner thinks this is a dual-language {s_or_d} file. Do you want to treat it as such? (If you press Yes, it will take about two minutes to process the file.)", default="yes", icon="question") logger.debug(" res = messagebox.askyesnocancel: res %s", res) if res is None: return if res: # handle bilingual text # bumblebee_aligner st-bee-aligner.py # p_list = text_to_plist(src_file, langs=s_or_d) # may need an indeterminate progressbar # p_list = text_to_plist(text1, langs=s_or_d) thr = Thread( target=text_to_plist, args=(text1, ), # kwargs=dict(langs=s_or_d), kwargs={"langs": s_or_d}, # target=longtime_job, # kwargs={"counter": 16}, # name='job_thr', ) thr.stop = False # type: ignore # prepare for check_thread_update1 # to set self.filename1/2 when successfully run thr.filename1 = file # type: ignore thr.filename2 = file # type: ignore thr.start() # refer to paligner.py self is Aligner rt = self.top # top = Pbar(rt) # this does not work top = tk.Toplevel(rt) pbar = Pbar(top) pbar.TProgressbar1.start(50) # check_thread_update1(thr, top, pbar) # check_thread_update1(thr, pbar) check_thread_update1(self, thr, pbar) # disable Pad editing blinker.signal("aligner").send( "open1_comman", pbtoplevel="True") # SIG_ALIGNER.send # update table via slot_table in text_to_plist # blinker.signal("table").send(df=df_data) # self.Table.model.df = DataFrame(p_list, columns=["text1", "text2", "merit"]) # self.filename1 = file # self.filename2 = file # self.text1 = "\n".join(self.Table.model.df.text1) # self.text2 = "\n".join(self.Table.model.df.text2) return None else: # user opts for single-lang # left: self.text1 part values = self.text1 df = self.Table.model.df df.columns = ["text1", "text2", "merit"] df = insert_column(values, df, 0) # reset merit column to all "" df = insert_column([""] * df.shape[0], df, 2) # cp_load_text1 self.Table.model.df = df # left: self.text1 part # self.filename1 = file else: # single-lang, normal # left: self.text1 part values = self.text1 df = self.Table.model.df df.columns = ["text1", "text2", "merit"] df = insert_column(values, df, 0) # reset merit column # self.Table.model.df.merit = "" df = insert_column([""] * df.shape[0], df, 2) # cp_load_text1 self.Table.model.df = df # logger.debug(self.Table.model.df) # data = extract_rows(self.Table.model.df, 0) data = extract_rows(self.Table.model.df, self.Table.row_clicked) logger.debug("data sent to SIG_PAD.send(data=data): %s", data) # SIG_TABLE.send(data=data) SIG_PAD.send(data=data) self.Table.show() self.Table.redraw() self.filename1 = file # logger.debug(" setting filename1 and QUEUE_T1") # logger.debug(" setting filename1 *%s* and QUEUE_T2", self.filename1) logger.debug(" setting filename1 *%s* and QUEUE_T1 self.text1[:3] %s", self.filename1, self.text1[:3]) queue1_put(QUEUE_T1, self.text1) queue1_put(QUEUE_P1, self.text1) if self.text1 and self.text2: self.sub_menu1.entryconfig("PAlign", state="normal") logger.debug( """ enabling PAlign: logger.debug(" enabling PAlign ") """)
def check_thread_update1(self, thr, pbar): """ check thread thr and update pbar via QUEUE. called in open1_command self is aligner """ # logger.debug(" thr.ident: %s", thr.ident) # pbar = win.pbar if thr.is_alive(): # logger.debug("+++ check_threa_update1 %s, thr.ident: %s, ++alive++ ", thr.name, thr.ident) # pbar.TProgressbar1.step() # pbar.TProgressbar1.after(500, lambda: check_thread_update1(thr, win, pbar)) pbar.TProgressbar1.after(500, lambda: check_thread_update1(self, thr, pbar)) else: # not thr.is_alive(), finished aligning logger.debug("+++ check_threa_update1 %s ++not alive++ ", thr.name) # thr.filename1/2 defined in open1_command.py self.filename1 = thr.filename1 self.filename2 = thr.filename2 # thr.p_list defined in text_to_plist thr.res try: p_list = thr.p_list except Exception as exc: logger.error("p_list = thr.p_list exc: %s", exc) # win.destroy() try: pbar.top.destroy() except Exception as exc1: logger.error(" pbar.top.destroy() exc: %s", exc1) messagebox.showerror("Bummer!", f" Oh no, sh*t happens too often: {exc} ") return None # _ = DataFrame(p_list) df = DataFrame(p_list) # logger.debug(" DataFrame(p_list).head(3): %s", df.head(3)) self.paras1 = df[0] self.paras2 = df[1] self.paras_merit = df[2] # self.text1 = "\n".join(self.paras1) # self.text2 = "\n".join(self.paras2) queue1_put(QUEUE_P1, self.paras1) queue1_put(QUEUE_P2, self.paras2) queue1_put(QUEUE_PM, self.paras_merit) # QUEUE_T1/2 only needed for first # palign_command/myprogressbar1/thread # queue1_put(QUEUE_T1, self.text1) # queue1_put(QUEUE_T2, self.text2) self.paligned = True queue1_put(QUEUE_PA, True) # QUEUE_PS also for another purpose: # controls branching in check_thread_update # self.Table.model.df currently is paras1/2/_merit queue1_put(QUEUE_PS, 'p') # update QUEUE_PS # cp_p logger.info("update: self.paras1/2/_merit, Q_P1/2/M self.text1/2, Q_T1/2 self.paligned/Q_PA ") logger.info("paras aligning completed.") # need a way to disable "PAlign" enable "SAlign" # blinker.signal("PAlign")? blinker.signal("SAlign") # self.sub_menu1.entryconfig("PAlign", state="disabled") logger.debug("""send blinker.signal to aligner slot: {"PAlign": False, "SAlign": True,}""") SIG_ALIGNER.send( "check_thread_update1", **{ "PAlign": False, "SAlign": True, "pbtoplevel": False, # grab_release, not really needed since pbar1 will be destroyed when done? } ) logger.debug(" <check_thread_update1> exit") # probably too cumbersome # SIG_FILENAMES.sender(filename1=thr.filename1) # SIG_FILENAMES.sender(filename2=thr.filename2) # pbar.destroy() # 'Pbar' object has no attribute 'destroy' # win.destroy() try: pbar.top.destroy() except Exception as exc: logger.error(" pbar.top.destroy() exc: %s", exc)
def start_command(self, event=None): """ need a QUEUE_PS (paras or sents flag). set when ativating palign or salign flag = QUEUE_PS.get_nowait() queue1_put(QUEUE_PS, flag) """ try: flag = QUEUE_PS.get_nowait() queue1_put(QUEUE_PS, flag) except Empty: flag = "" # ######### SENTS ########### # 358 - 475 salign if flag in ["s"]: logger.debug("salign myprogressbar.start_command") logger.info("handle salign...") # check_thread_update # pbar (self) TButton1: Start, 2: Cancel,3: Back self.TButton1.config(state=tk.DISABLED) self.TButton2.config(state=tk.NORMAL) self.TButton3.config(state=tk.DISABLED) if not QUEUE_PA.qsize(): messagebox.showwarning( title="Not ready", message= " Paras not aligned yet, align paras first (Ctrl-P) ") # restore button state 1: Start, 2: Cancel, 3: Back self.TButton1.config(state=tk.DISABLED) self.TButton2.config(state=tk.DISABLED) self.TButton3.config(state=tk.NORMAL) return None try: paras1 = QUEUE_P1.get_nowait() logger.debug(" paras1[:3]: %s", paras1[:3]) queue1_put(QUEUE_P1, paras1) except Exception as exc: logger.error(" QUEUE_P1.get_nowait() exc: %s", exc) return None try: paras2 = QUEUE_P2.get_nowait() queue1_put(QUEUE_P2, paras2) except Exception as exc: logger.error(" QUEUE_P2.get_nowait() exc: %s", exc) return None try: parasm = QUEUE_PM.get_nowait() queue1_put(QUEUE_PM, parasm) except Exception as exc: logger.error(" QUEUE_PM.get_nowait() exc: %s", exc) return None lang0 = Detector(" ".join(paras1)).language.code lang1 = Detector(" ".join(paras2)).language.code # plist = [*zip_longest(paras1, paras2, parasm)] # QUEUE_DF, model.df try: # plist = QUEUE_DF[0] qdf = QUEUE_DF[0] except IndexError: logger.error(" qdf = QUEUE_DF[0] IndexError") messagebox.showwarning(" Oh no!", "Nothing in QUEUE_DF") return None except Exception as exc: logger.error(" qdf = QUEUE_DF[0] exc: %s", exc) messagebox.showwarning( " Oh no!", "unable to obtain data frmo QUEUE_DF exc: %s" % exc) return None # slist = plist_to_slist(plist, lang0, lang1) # tot = len(slist) * 2 tot = len(qdf) * 2 if tot > 300: msg = f"This can take about {get_time(tot)}. Continue?" logger.debug(msg) res = messagebox.askyesnocancel("Continue?", message=msg) if not res: return # get QUEUE_PS and QUEUE_PS0 if both 's', set split=Fasle try: qps0 = QUEUE_PS0[0] except IndexError: qps0 = "" # fetch QUEUE_PS and restore qps = fetch_queue1(QUEUE_PS) logger.debug(" qps0: %s qps0, qps: %s", qps0, qps) split = True if qps0 == qps: split = False plist = [*zip_longest( qdf["text1"], qdf["text2"], qdf["merit"], )] logger.debug("split: %s, plist[:5]: %s", split, plist[:5]) thr = Thread(target=plist_to_flist, args=(plist, ), kwargs={ "lang0": lang0, "lang1": lang1, "split": split }) thr.stop = False # type: ignore thr.start() self.TProgressbar1.start() # for mode="indeterminate" check_thread_update(self, thr) signal = { "PAlign": False, "SAlign": False, "pbtoplevel": True, # pbar grab_set, prevent editing Pad } logger.debug( """pbar send blinker.signal to aligner slot, signal: %s """, signal) SIG_ALIGNER.send("check_thread_update1", **signal) logger.debug(" pbar-s exit ") return None # ######### PARAS ########### logger.debug("palign myprogressbar.start_command") if event: # print(event) logger.debug("event: %s", event) # if tkMessageBox.askokcancel # self.top.destroy(); # self.start_command() # pbar = Mypbar(top): self.top = top => top = Aligner # self == pbar? # self.top: TopLevel # needs Aligner # self.top.align_command() # pbar (self) TButton1: Start, 2: Cancel,3: Back self.TButton1.config(state=tk.DISABLED) self.TButton2.config(state=tk.NORMAL) self.TButton3.config(state=tk.DISABLED) _ = """ thr = Thread( target=longtime_job, # name='job_thr', kwargs={"counter": 10}, ) # """ # src_text # type: Union[str, List[str] # tgt_text # type: Union[str, List[str] try: src_text = QUEUE_T1.get_nowait() queue1_put(QUEUE_T1, src_text) except Empty: src_text = "" try: tgt_text = QUEUE_T2.get_nowait() queue1_put(QUEUE_T2, tgt_text) except Empty: tgt_text = "" if not (src_text and tgt_text): messagebox.showwarning( title="Not ready", message=" Empty src_text or tgt_text, load files first. ") # restore button state 1: Start, 2: Cancel, 3: Back self.TButton1.config(state=tk.DISABLED) self.TButton3.config(state=tk.NORMAL) self.TButton2.config(state=tk.DISABLED) return None logger.debug("src_text[:5]: %s", src_text[:5]) logger.debug("tgt_text[:5]: %s", tgt_text[:5]) try: src_lang = Detector("\n".join(src_text)).language.code except Exception as exc: # messagebox.showerror(" Oh no! ", str(exc)) # self.TButton1.config(state=tk.DISABLED) # self.TButton3.config(state=tk.NORMAL) # self.TButton2.config(state=tk.DISABLED) # return None logger.error( """src_lang = Detector("\n".join(src_text)).language.code exc: %s""", exc) src_lang = "en" try: tgt_lang = Detector("\n".join(tgt_text)).language.code except Exception as exc: # messagebox.showerror(" Oh no! ", str(exc)) # self.TButton1.config(state=tk.DISABLED) # self.TButton3.config(state=tk.NORMAL) # self.TButton2.config(state=tk.DISABLED) # return None logger.error( """tgt_lang = Detector("\n".join(tgt_text)).language.code exc: %s""", exc) tgt_lang = "en" # convert to lists, already lists # src_text = text_to_paras(src_text) # tgt_text = text_to_paras(tgt_text) tot = len(src_text) + len(tgt_text) logger.debug( "tot: %s, len(src_text): %s, len(tgt_text): %s, src_text[:3]: %s, tgt_text[:3]: %s", tot, len(src_text), len(tgt_text), src_text[:3], tgt_text[:3]) if tot > 300: msg = f"This can take about {get_time(tot)}. Continue?" logger.debug(msg) res = messagebox.askyesnocancel("Continue?", message=msg) if not res: self.TButton1.config(state=tk.DISABLED) self.TButton3.config(state=tk.NORMAL) self.TButton2.config(state=tk.DISABLED) return # cos_mat = bee_corr(src_text, tgt_text, src_lang, tgt_lang) # plist = bee_aligner(src_text, tgt_text, cos_mat) thr = Thread( target=bee_aligner, args=(src_text, tgt_text), kwargs={"thr": self.spinbox_value}, ) logger.debug(" self.spinbox_value: %.2f, %s", self.spinbox_value, type(self.spinbox_value)) thr.stop = False # type: ignore thr.start() logger.debug("*job* thr_name: %s", thr.name) # thr.value = 0 # check_thread(thr) # self: pbar # reset pbar self.TProgressbar1["value"] = 0 self.TProgressbar1.step(100) self.TProgressbar1.start() # for mode="indeterminate" check_thread_update(self, thr) # thr.join()? fetch result from longtime_job # thr.join() will block, hence nonresponsive signal = { "PAlign": False, # "SAlign": True, "pbtoplevel": True, # pbar grab_set, prevent editing Pad } logger.debug("""send blinker.signal to aligner slot, signal: %s """, signal) SIG_ALIGNER.send("check_thread_update", **signal) logger.debug(" pbar-p exit ")
def __init__(self, top=None): """This class configures and populates the toplevel window. top is the toplevel containing window.""" super().__init__() self.top = top iconpath = Path(__file__).parent / "align.ico" # top.iconbitmap("align.ico") top.iconbitmap(iconpath) self.spinbox_value = 0.64 _bgcolor = "#d9d9d9" # X11 color: 'gray85' _fgcolor = "#000000" # X11 color: 'black' _compcolor = "#d9d9d9" # X11 color: 'gray85' _ana1color = "#d9d9d9" # X11 color: 'gray85' # noqa: F841 _ana2color = "#ececec" # Closest X11 color: 'gray92' font9 = ("-family {Segoe UI} -size 9 -weight normal -slant " "roman -underline 0 -overstrike 0") self.style = ttk.Style() if sys.platform == "win32": self.style.theme_use("winnative") self.style.configure(".", background=_bgcolor) self.style.configure(".", foreground=_fgcolor) self.style.configure(".", font="TkDefaultFont") self.style.map(".", background=[("selected", _compcolor), ("active", _ana2color)]) top.geometry("702x50+279+79") top.title("Pbar") top.configure(background="#d9d9d9") top.configure(highlightbackground="#d9d9d9") top.configure(highlightcolor="black") self.TProgressbar1 = ttk.Progressbar(top) self.TProgressbar1.place(relx=0.0, rely=0.0, relwidth=1.0, relheight=0.0, height=25) self.TProgressbar1.configure(variable=myprogressbar_ui_support.pbarvar) self.TProgressbar1.configure(takefocus="0") self.TProgressbar1.configure(mode="indeterminate") self.TFrame1 = ttk.Frame(top) self.TFrame1.place(relx=0.0, rely=0.5, relheight=0.5, relwidth=1.0) self.TFrame1.configure(relief="groove") self.TFrame1.configure(borderwidth="2") self.TFrame1.configure(relief="groove") self.TFrame1.configure(width=678) self.TButton1 = ttk.Button(self.TFrame1) self.TButton1.place(relx=0.698, rely=0.0, height=25, width=70) self.TButton1.configure(command=self.start_command) self.TButton1.configure(takefocus="") self.TButton1.configure(text="""Start""") self.TButton2 = ttk.Button(self.TFrame1) self.TButton2.place(relx=0.897, rely=0.0, height=25, width=70) self.TButton2.configure(command=self.cancel_command) self.TButton2.configure(takefocus="") self.TButton2.configure(text="""Cancel""") self.Spinbox1 = tk.Spinbox(self.TFrame1, from_=0.5, to=0.95) self.Spinbox1.place(relx=0.648, rely=0.0, relheight=1.0, relwidth=0.05) self.Spinbox1.configure(activebackground="#f9f9f9") self.Spinbox1.configure(background="white") self.Spinbox1.configure(buttonbackground="#d9d9d9") self.Spinbox1.configure(disabledforeground="#a3a3a3") self.Spinbox1.configure(font=font9) self.Spinbox1.configure(foreground="black") self.Spinbox1.configure(highlightbackground="black") self.Spinbox1.configure(highlightcolor="black") self.Spinbox1.configure(increment="0.01") self.Spinbox1.configure(insertbackground="black") self.Spinbox1.configure(selectbackground="#c4c4c4") self.Spinbox1.configure(selectforeground="black") self.Spinbox1.configure(textvariable=myprogressbar_ui_support.spinbox) self.TButton3 = ttk.Button(self.TFrame1) self.TButton3.place(relx=0.798, rely=0.0, height=25, width=70) self.TButton3.configure(command=self.back_command) self.TButton3.configure(takefocus="") self.TButton3.configure(text="""Back""") self.Label_threshold = tk.Label(self.TFrame1) self.Label_threshold.place(relx=0.499, rely=0.0, height=25, width=105) self.Label_threshold.configure(activebackground="#f9f9f9") self.Label_threshold.configure(activeforeground="black") self.Label_threshold.configure(background="#d9d9d9") self.Label_threshold.configure(disabledforeground="#a3a3a3") self.Label_threshold.configure(foreground="#000000") self.Label_threshold.configure(highlightbackground="#d9d9d9") self.Label_threshold.configure(highlightcolor="black") spinbox = myprogressbar_ui_support.spinbox myprogressbar_ui_support.set_Tk_var() def update_label_threhold(*args): """ update_label_threhold. """ logger.debug("args: %s", args) spinbox_value = spinbox.get() self.Label_threshold.configure( text=f"""Threshold {spinbox_value}""") # QUEUE_SPINBOX is really not necessary? # update spinbox_value to QUEUE_SPINBOX # print('__file__: ', __file__, f'placing spinbox [{spinbox_value}] in QUEUE_SPINBOX') logger.debug( "spinbox_value [%s] in QUEUE_SPINBOX", spinbox_value, ) # QUEUE_SPINBOX.put(spinbox_value) try: self.spinbox_value = float(spinbox_value) except Exception as exc: logger.error( " self.spinbox_value = float(spinbox_value) exc: %s", exc) self.spinbox_value = 0.64 logger.debug( "self.spinbox_value [%s] in QUEUE_SPINBOX", self.spinbox_value, ) queue1_put(QUEUE_SPINBOX, spinbox_value) spinbox.trace_variable("w", update_label_threhold) # use self.spinbox to remember spinbox # in the previous iteration try: queue_spinbox = QUEUE_SPINBOX.get_nowait() queue1_put(QUEUE_SPINBOX, queue_spinbox) except Empty: logger.error(" QUEUE_SPINBOX.get_nowait Empty, set to 0.64") queue_spinbox = 0.64 except Exception as exc: logger.error(" QUEUE_SPINBOX.get_nowait() exc %s", exc) queue_spinbox = 0.64 # print(f' <myprogressbar.py> __file__: {Path(__file__).name}', f'queue_spinbox: {queue_spinbox}') try: spinbox_value = float(queue_spinbox) # initially set to '' except ValueError: spinbox_value = 0.64 spinbox.set(spinbox_value) logger.debug(" spinbox_value (threshold) set to %s", spinbox_value) try: self.spinbox_value = float(spinbox_value) except Exception as exc: logger.error(" self.spinbox_value = float(spinbox_value) exc: %s", exc) self.spinbox_value = 0.64 self.Label_srtatus = tk.Label(self.TFrame1) self.Label_srtatus.place(relx=0.0, rely=0.0, height=25, width=337) self.Label_srtatus.configure(activebackground="#f9f9f9") self.Label_srtatus.configure(activeforeground="black") self.Label_srtatus.configure(background="#d9d9d9") self.Label_srtatus.configure(disabledforeground="#a3a3a3") self.Label_srtatus.configure(foreground="#000000") self.Label_srtatus.configure(highlightbackground="#d9d9d9") self.Label_srtatus.configure(highlightcolor="black") self.Label_srtatus.configure(justify="left") self.Label_srtatus.configure( textvariable=myprogressbar_ui_support.statustext)