1
0
Эх сурвалжийг харах

feat: 从文件读取单词

SongZihuan 3 жил өмнө
parent
commit
4c1be350ab
4 өөрчлөгдсөн 92 нэмэгдсэн , 47 устгасан
  1. 34 39
      db.py
  2. BIN
      resource/English-World.db
  3. 58 5
      ui.py
  4. 0 3
      word.py

+ 34 - 39
db.py

@@ -12,12 +12,7 @@ import re
 
 class DataBase:
     def __init__(self, name):
-        self._db = sqlite3.connect(f"{name}.db")
-        self._cursor = self._db.cursor()
-        self._lock = threading.RLock()
-
-    def get_cursor(self) -> sqlite3.Cursor:
-        return self._cursor
+        self._db_name = f"{name}.db"
 
     def search(self, columns: List[str], table: str,
                where: Union[str, List[str]] = None,
@@ -93,39 +88,32 @@ class DataBase:
         kw_str = ", ".join(kw_list)
         return self.done(f"UPDATE {table} SET {kw_str} WHERE {where};", not_commit=not_commit)
 
-    def __search(self, sql) -> Union[None, sqlite3.Cursor]:
+    def __search(self, sql) -> Union[None, List]:
         try:
-            self._lock.acquire()  # 上锁
-            self._cursor.execute(sql)
+            sqlite = sqlite3.connect(self._db_name)
+            cur = sqlite.cursor()
+            cur.execute(sql)
+            ret = cur.fetchall()
         except sqlite3.Error:
             traceback.print_exc()
             print(f"sql='{sql}'")
             return None
-        finally:
-            self._lock.release()  # 释放锁
-        return self._cursor
+        return ret
 
-    def done(self, sql, not_commit: bool = False) -> Union[None, sqlite3.Cursor]:
+    def done(self, sql, not_commit: bool = False) -> Union[None, "Tuple[sqlite3, sqlite3.Cursor]"]:
+        sqlite = sqlite3.connect(self._db_name)
         try:
-            self._lock.acquire()
-            self._cursor.execute(sql)
+            cur = sqlite.cursor()
+            cur.execute(sql)
         except sqlite3.Error:
-            self._db.rollback()
+            sqlite.rollback()
             print(f"sql={sql}")
             traceback.print_exc()
             return None
         finally:
             if not not_commit:
-                self._db.commit()
-            self._lock.release()
-        return self._cursor
-
-    def commit(self):
-        try:
-            self._lock.acquire()
-            self._db.commit()
-        finally:
-            self._lock.release()
+                sqlite.commit()
+        return sqlite, cur
 
 
 class WordDatabase(DataBase):
@@ -147,12 +135,11 @@ class WordDatabase(DataBase):
         self.wd = word.WordDict()
 
     def find_word(self, q: str) -> Optional[word.Word]:
-        cur = self.search(columns=["id", "word", "part", "english", "chinese", "eg"],
+        res = self.search(columns=["id", "word", "part", "english", "chinese", "eg"],
                           table="Word",
                           where=f"LOWER(word)='{q.lower()}'")
-        res = []
-        if cur is not None:
-            res = cur.fetchall()
+        if res is None:
+            res = []
 
         if len(res) <= 0:
             r = self.wd.get_requests(q)
@@ -165,8 +152,8 @@ class WordDatabase(DataBase):
                     ret = w
                 name = w.name
                 name_lower = name.lower().replace("'", "''")
-                cur = self.search(columns=["word"], table="Word", where=f"LOWER(word)='{name_lower}'")
-                if cur is not None and len(cur.fetchall()) > 0:
+                res = self.search(columns=["word"], table="Word", where=f"LOWER(word)='{name_lower}'")
+                if res is not None and len(res) > 0:
                     continue
                 for c in w.comment:
                     comment = r.res[i].comment[c]
@@ -251,12 +238,11 @@ class WordDatabase(DataBase):
         return True, response
 
     def export_as_txt(self, file: str):
-        cur = self.search(columns=["word"],
+        res = self.search(columns=["word"],
                           table="Word",
                           order_by=[('box', 'DESC')])
-        if cur is None:
+        if res is None:
             return False
-        res = cur.fetchall()
         export = []
         with open(file + '.txt', encoding='utf-8', mode="w") as f:
             for i in res:
@@ -266,16 +252,15 @@ class WordDatabase(DataBase):
                 export.append(i[0])
         return True
 
-    def export_as_table(self, file: str, t: str = 'excel'):
+    def export_as_table(self, file: str, t: str = 'excel', max_eg: int = 3):
         if t == 'txt':
             return self.export_as_txt(file)
 
-        cur = self.search(columns=["box", "word", "part", "english", "chinese", "eg"],
+        res = self.search(columns=["box", "word", "part", "english", "chinese", "eg"],
                           table="Word",
                           order_by=[('box', 'DESC')])
-        if cur is None:
+        if res is None:
             return False
-        res = cur.fetchall()
         df = pandas.DataFrame(columns=["Box", "Word", "Part", "English", "Chinese", "Eg"])
         export = []
         for i in res:
@@ -284,7 +269,12 @@ class WordDatabase(DataBase):
             export.append(i[1])
             eg = i[5].split("@@")
             eg_str = ""
+            count_eg = 0
             for e in eg:
+                count_eg += 1
+                if max_eg != -1 and count_eg > max_eg:
+                    break
+
                 ec = e.split("##")
                 if len(ec) == 2:
                     eng, chi = ec
@@ -308,3 +298,8 @@ class WordDatabase(DataBase):
             df.to_json(file + ".json", encoding='utf-8')
         else:
             return False
+
+
+if __name__ == '__main__':
+    db = WordDatabase()
+    db.export_as_table("resource/English-Word")

BIN
resource/English-World.db


+ 58 - 5
ui.py

@@ -1,8 +1,14 @@
 import tktool
 import tkinter
+import tkinter.ttk as ttk
+import tkinter.filedialog as fd
+import tkinter.messagebox as msg
 from typing import List, Tuple, Callable, Optional
 import abc
 
+import db
+import word
+
 
 class HEnglishTkinter(tktool.TkEventMain, metaclass=abc.ABCMeta):
     tk_zoom = 1
@@ -25,6 +31,7 @@ class HEnglishTkinter(tktool.TkEventMain, metaclass=abc.ABCMeta):
 
         if top:
             self._window = tkinter.Toplevel(top._window)
+            top._window.lift()
         else:
             self._window = tkinter.Tk()
 
@@ -71,6 +78,8 @@ class HEnglishTkinter(tktool.TkEventMain, metaclass=abc.ABCMeta):
 class HEnglish(HEnglishTkinter):
     def __init__(self):
         super(HEnglish, self).__init__("H-English")
+        self.db = db.WordDatabase()
+        self.wd = self.db.wd
 
     def _create_windows(self):
         self._title_label = tkinter.Label(self._window)
@@ -142,6 +151,36 @@ class HEnglish(HEnglishTkinter):
 
 
 class Import(HEnglishTkinter):
+    class ImportEvent(tktool.TkEventBase, metaclass=abc.ABCMeta):
+        def __init__(self, imp: "Import"):
+            super().__init__()
+            self.imp = imp
+            self.thread = None
+
+        def get_title(self) -> str:
+            return "Import"
+
+    class ImportFromText(ImportEvent):
+        def func(self, file: str):
+            self.file = file
+            return self.imp._father.db.update_from_txt(file)
+
+        def __init__(self, imp: "Import"):
+            super().__init__(imp)
+            self.file = ""
+
+        def start(self, file: str):
+            self.thread = tktool.TkThreading(self.func, file)
+            return self
+
+        def is_end(self) -> bool:
+            return not self.thread.is_alive()
+
+        def done_after_event(self):
+            res = self.thread.wait_event()
+            if res:
+                msg.showinfo("操作成功", f"成功从{self.file}中读取单词")
+
     def __init__(self, father: HEnglish, father_windows: tkinter.Tk):
         super(Import, self).__init__("Import", father, size=(1 / 3, 1 / 3))
         self._father = father
@@ -149,10 +188,12 @@ class Import(HEnglishTkinter):
 
     def _create_windows(self):
         self._title_label = tkinter.Label(self._window)
+        self._loading_pro = ttk.Progressbar(self._window)
         self._control_btn = [tkinter.Button(self._window) for _ in range(6)]
 
     def _set_windows(self):
         self.__conf_title()
+        self.__conf_loader()
         self.__conf_control_btn()
 
     def __conf_title(self):
@@ -167,6 +208,11 @@ class Import(HEnglishTkinter):
         self._title_label.place(relx=0.0, rely=0.03, relwidth=1.0, relheight=0.13)
         self._title = tkinter.Label()
 
+    def __conf_loader(self):
+        self._loading_pro['mode'] = 'indeterminate'  # 来回显示
+        self._loading_pro['orient'] = 'horizontal'  # 横向进度条
+        self._loading_pro['maximum'] = 100
+
     def __conf_control_btn(self):
         if self._win_width >= self._win_height:
             font = tktool.make_font(size=int(self._win_height * 0.04))
@@ -184,7 +230,7 @@ class Import(HEnglishTkinter):
         for i in zip(self._control_btn,
                      ["From Text", "From CSV", "From Excel", "From Json"],
                      ["#1E90FF", "#FF69B4", "#C71585", "#00FF7F"],
-                     [None, None, None, None]):
+                     [self.import_from_text, None, None, None]):
             i[0]['font'] = font
             i[0]['fg'] = "#000000"
             i[0]['bg'] = i[2]
@@ -196,11 +242,18 @@ class Import(HEnglishTkinter):
             i[0]['text'] = i[1]
             i[0]['command'] = i[3]
 
-    def show_loading(self, title: str):  # 有子线程时显示加载
-        ...
+    def import_from_text(self):
+        file = fd.askopenfilename(filetypes=[("Text", ".txt"), ("All", "*")])
+        self.push_event(self.ImportFromText(self).start(file))
 
-    def stop_loading(self):  # 子线程运行完成后关闭加载
-        ...
+    def show_loading(self, title: str):
+        self._loading_pro['value'] = 0
+        self._loading_pro.place(relx=0.10, rely=0.17, relwidth=0.80, relheight=0.05)
+        self._loading_pro.start(50)
+
+    def stop_loading(self):
+        self._loading_pro.place_forget()
+        self._loading_pro.stop()
 
 
 if __name__ == '__main__':

+ 0 - 3
word.py

@@ -142,6 +142,3 @@ class Word:
         for i in self.comment:
             ret += f'note: {self.comment[i]};\n'
         return ret
-
-
-word_dict = WordDict()