主頁 > 軟體工程 > EXETkinter問題:退出程式時資料丟失

EXETkinter問題:退出程式時資料丟失

2022-06-20 09:56:35 軟體工程

我用 Tkinter 在 python 中制作了一個 GUI。現在我只想創建一個可執行檔案(.exe),這樣任何人都可以使用我的程式。該程式必須記錄資料(目的是遵循管理指標),因此必須存盤和訪問資料。我需要能夠使用我的 exe 執行我的 CRUD(創建、讀取、更新、洗掉)。

為此,我使用 sqlite3。 當我從 VSCode 運行我的程式時: 資料保存得很好,當我關閉程式并重新運行它時,我找到了我所有的資料。一切正常。

問題: 現在,當我啟動同一個程式的 .exe 時,(我使用 auto-py-to-exe 構建 exe:我只選擇了我的 python 腳本以及我的檔案,它創建了一個 exe)。當我運行我的 exe 時,我可以保存我的資料。但是當我關閉我的 exe 并重新打開它時,我的所有資料都丟失了!

我簡化了代碼以理解問題。因此,我創建了在用戶選擇樹視圖小部件中的第 6 行時觸發的方法。這將打開一個顯示資料的新視窗。當我點擊按鈕時,新資料被保存。

我無法完整發送所有代碼,所以我只發送包含在“if chooseUser == 6”塊中的代碼。這些是基本的方法。目標是簡化問題: ? 方法生成唯一識別符號 ? 方法回傳當前日期和時間 ? 方法檢查資料庫是否已存在。如果它不存在,它會創建它。? 方法檢索資料 ? 方法根據識別符號洗掉資料 ? 方法將資料保存在 2 個表中:oa 表稱為“history”:它有 2 列:scan_id 和 date_scan o 第二個表稱為:“indica ":它有 3 列:scan_idi、data_one、data_two 這是代碼:

            if choixUser ==6:
                win_debug = Toplevel(newWindow, bg="black")
                win_debug.geometry("480x350")
                win_debug.minsize(width=480, height=350)
                win_debug.maxsize(width=480, height=350)
    
                win_debug.resizable(height = None, width = None)
                win_debug.geometry(f" {root.winfo_x() 500} {root.winfo_y() 100}") # 
                
                def random_id():
                    b1 = random.choice(string.ascii_uppercase)
                    b2 = random.choice(string.ascii_uppercase)
                    b3 = random.randint(10000,99999)
                    b4 = random.choice(string.ascii_lowercase)
                    b5 = random.randint(10,99)
                    id = f"{b1}{b2}-{b3}{b4}-{b5}"
                    return id
                
                def gimme_the_date_now():
                    date = datetime.now()
                    out_format = "%d/%m/%Y %H:%M:%S"
                    date_formatee = datetime.strftime(date, out_format)
                    return date_formatee

                def verify_or_create_DB():
                    connexion= sqlite3.connect('astupiddb.db')
                    cursor = connexion.cursor()
                    command1 = """CREATE TABLE IF NOT EXISTS history(scan_id TEXT PRIMARY KEY, datescan TEXT)"""
                    command2 = """CREATE TABLE IF NOT EXISTS indic(scan_id TEXT, data_one TEXT, data_two DOUBLE)"""
                    cursor.execute(command1)
                    cursor.execute(command2)

                def fetch_datas(table):
                    connexion= sqlite3.connect('astupiddb.db')
                    query = f"SELECT * FROM {table}"
                    result = pd.read_sql(query, connexion)
                    result = pd.DataFrame(result)
                    return result

                def suppr_data_with_the_id(id):        
                    connexion= sqlite3.connect('astupiddb.db')
                    command1 = f"""DELETE FROM history WHERE scan_id =?"""
                    cursor = connexion.cursor()
                    cursor.execute(command1, (id,))
                    connexion.commit()
                        
                    command2 = f"""DELETE FROM indic WHERE scan_id =?"""
                    cursor = connexion.cursor()
                    cursor.execute(command2, (id,))
                    connexion.commit()

                def send_Datas_to_DB(dataFrame1, dataFrame2):
                    connexion= sqlite3.connect('astupiddb.db')
                    dataFrame1.to_sql('history', connexion, if_exists="append", index=False)
                    dataFrame2.to_sql('indic', connexion, if_exists="append", index=False)  
                    connexion.commit()
                    connexion.close()
                          
                def prepareData_and_store():
                    id_Scan = random_id()
                    date_Scan = gimme_the_date_now()
                    d1 = random.choice(string.ascii_uppercase)
                    d2 = random.randint(10000,99999)
                    
                    DATAFRAME_ONE = pd.DataFrame(columns=["scan_id","datescan"])
                    DATAFRAME_ONE= DATAFRAME_ONE.append({"scan_id":id_Scan,"datescan":date_Scan},ignore_index=True)

                    DATAFRAME_TWO = pd.DataFrame(columns=["scan_id","data_one","data_two"])
                    DATAFRAME_TWO= DATAFRAME_TWO.append({"scan_id":id_Scan,"data_one":d1,"data_two":d2},ignore_index=True)
                    
                    send_Datas_to_DB(DATAFRAME_ONE,DATAFRAME_TWO)
                
                verify_or_create_DB()
                columns_tree = ('scan_id','datescan','data_one','data_two')
                tree = ttk.Treeview(win_debug, columns=columns_tree, show='headings', selectmode='browse')
                tree.column('#1', minwidth = 80, width = 80, stretch = False)
                tree.column('#2', minwidth = 80, width = 80, stretch = False)
                tree.column('#3', minwidth = 80, width = 80, stretch = False)
                tree.column('#4', minwidth = 80, width = 80, stretch = False)

                tree.heading('scan_id', text='scan id')
                tree.heading('datescan', text='datescan')
                tree.heading('data_one', text='data_one')
                tree.heading('data_two', text='data_two')
                tree.place(x=10,y=10)
                    # Barre de scroll:
                scrollbar = ttk.Scrollbar(win_debug, orient="vertical", command=tree.yview)
                scrollbar.place(x=10 320 3, y=10, height=225 2)
                tree.configure(yscroll=scrollbar.set)   
                    
                result_datas = fetch_datas("history")
                result_datas_2 = fetch_datas("indic")
                all_datas = result_datas_2.merge(result_datas, how="left", on="scan_id")

                all_datas["datescan"] = pd.to_datetime(all_datas["datescan"],format="%d/%m/%Y %H:%M:%S")
                all_datas = all_datas.sort_values(by="datescan", ascending=False)
                    
                for index,row in all_datas.iterrows():
                        scan_id = row["scan_id"]
                        date_scan = row["datescan"]
                        data_one = row["data_one"]
                        data_two = row["data_two"]
                        # L'attribut text correspond à la colonne #0
                        tree.insert("", "end", values = (scan_id, date_scan, data_one,data_two))

                one_button = tkinter.Button(win_debug,text="i store in the memory",command=prepareData_and_store)
                one_button.place(x=330,y=250)

這是總結我的問題的影像: 在此處輸入影像描述

由于Py到exe生成的臨時檔案夾,這是我用來重新定義路徑的函式:

def path_pour_wrapExe(fichier):
    # pour les versions >=1.6
    if hasattr(sys, '_MEIPASS'):
        chdir(sys._MEIPASS)
        fichier = join(sys._MEIPASS, fichier)
        # Pour les versions <1.6
    elif '_MEIPASS2' in environ:
        chdir(environ['_MEIPASS2'])
        fichier = join(environ['_MEIPASS2'], fichier)
        # Pour le développement
    else:
        chdir(dirname(sys.argv[0]))
        fichier = join(dirname(sys.argv[0]), fichier)
    return fichier

從昨天開始,我一直被這個可執行問題所困擾,一旦關閉就會丟失資料。如果我不能解決這個問題,我的程式將無法使用? 你是我最后的希望!

更新:當我選擇在一個目錄模式下構建我的 exe 時,它??可以作業。但我需要將所有內容包裝在一個唯一的 exe 檔案中!怎么辦呢?

更新:我使用了Roland Smith的解決方案,并設法將所有內容包裝在一個 exe 中:它可以作業,謝謝 Roland!這是解決臨時檔案問題的函式:

    user_folder = os.environ["HOMEPATH"]
    engine = create_engine(f'sqlite:///C:\{user_folder}\nameofadatabase.db',echo=True)

uj5u.com熱心網友回復:

當您使用“一個檔案”模式時PyInstallerauto-py-to-exe前端)所做的就是將您的腳本、資料和庫打包到一個可執行程式中。

當您運行該程式時,它會將可執行檔案解壓縮到一個臨時目錄中并從那里運行您的腳本。

所以當你運行程式時,它可能會更新資料庫就好了。但是(這里我們遇到了問題)當程式關閉時,臨時目錄被洗掉,并且可執行檔案沒有使用臨時檔案夾的任何修改內容進行更新。

編輯:

我看到兩種可能的解決方案:

  1. 請改用“一個檔案夾”打包方法。您將檔案夾作為 ZIP 檔案提供給用戶。用戶將 ZIP 檔案解壓縮到一個檔案夾中并從該檔案夾啟動程式。這解決了問題,因為檔案夾在每次使用后都不會被洗掉。所以任何修改過的資料庫檔案都將保留。

  2. 如果您仍想使用“一個檔案”方法,請在用戶的主目錄中創建并保存資料庫。(應該os.environ["HOMEPATH"]在 ms-windows 上。)

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/492984.html

標籤:Python sqlite tkinter 可执行程序 在记忆中

上一篇:Python:Tkinter:使用place()從其中心移動物件

下一篇:tkinter在“輸入”按下時列印值

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more