Python - 快遞追蹤管理系統



在這裡,我們將學習如何使用 Python tkinter 庫和 SQLite 資料庫設計一個快遞追蹤管理系統,該系統具有使用者註冊、登入以及透過手機號碼追蹤貨物狀態等功能。

功能

此應用程式包含以下功能:

  • 重複註冊和登入選項
  • 它還支援透過手機號碼追蹤貨物。
  • 包括告知客戶產品和目的地資訊。

所需庫

要建立快遞追蹤管理系統,您需要安裝以下庫:

  • tkinter − 它是一個 Python 的內建 GUI 介面,主要用於建立基於視窗的應用程式。它用於開發使用者介面,以便使用者能夠與系統互動。
  • SQLite3 − SQLite 是一個 C 庫,它以 x86 機器碼實現,是一個輕量級的基於磁碟的資料庫。它非常適合小型應用程式,在這種應用程式中不需要資料庫伺服器的全部服務。使用 SQLite 不需要單獨安裝,因為它包含在 Python 中。
  • random − random 模組用於獲取產品的隨機貨物編號。此模組是 Python 的一部分,您無需安裝它。

應用程式工作流程和功能元件

1. 資料庫設定

首先建立一個 SQLite 資料庫,並定義一個 user 表來儲存使用者的使用者名稱、密碼和手機號碼。CREATE TABLE IF NOT EXISTS 查詢確保表僅在不存在時才建立。

2. 類結構

程式的主要功能位於主類中。在這裡,我們看到控制 GUI 行為和資料庫互動的所有變數和方法。

3. 登入

login() 方法將使用者輸入的憑據與 SQLite 資料庫中的記錄進行比較。如果憑據匹配,則對使用者進行身份驗證並允許其追蹤產品。

4. 新使用者註冊

new_user() 方法中,我們允許新使用者透過輸入使用者名稱、密碼和手機號碼建立帳戶。系統會在將新記錄新增到資料庫之前檢查使用者名稱是否存在。

5. 追蹤快遞

登入後,使用者可以透過輸入手機號並選擇產品來追蹤他們的快遞。快遞方法從資料庫中檢索快遞詳情,在UI中顯示它們,並生成一個隨機的產品ID。

6. GUI 元件

元件方法定義所有GUI元件,包括標籤、輸入欄位、按鈕和組合框。它建立登入、註冊和貨物追蹤表單的主佈局。

快遞追蹤管理系統 Python 程式碼

以下是設計此應用程式的完整程式碼:

from tkinter import *
from tkinter import messagebox as ms
from tkinter import ttk
import sqlite3
import random

# Database
with sqlite3.connect('Akash5.db') as db:
   c = db.cursor()
try:
   c.execute('CREATE TABLE IF NOT EXISTS user (username TEXT NOT NULL, password TEXT NOT NULL, mobile TEXT NOT NULL);')
except:
   pass
db.commit()
db.close()

class main:
   def __init__(self, master):
      self.master = master

      self.username = StringVar()
      self.password = StringVar()
      self.n_username = StringVar()
      self.n_password = StringVar()
      self.n_reg = StringVar()
      self.n_mobile = StringVar()
      self.mobile11 = StringVar()
      self.destination = StringVar()
      self.selected_product = StringVar()
      self.widgets()

   def login(self):
      with sqlite3.connect('Akash5.db') as db:
         c = db.cursor()

         find_user = ('SELECT * FROM user WHERE username = ? and password = ?')
         c.execute(find_user, [(self.username.get()), (self.password.get())])
         result = c.fetchall()

      if result:
         self.track()
      else:
         ms.showerror('Oops!', 'Username Not Found.')

   def new_user(self):
      with sqlite3.connect('Akash5.db') as db:
         c = db.cursor()
      if self.n_username.get() != ' ' and self.n_password.get() != ' ' and self.n_mobile.get() != ' ':
         find_user = ('SELECT * FROM user WHERE username = ?')
         c.execute(find_user, [(self.n_username.get())])

      if c.fetchall():
         ms.showerror('Error!', 'Username Taken. Try a Different One.')
      else:
         insert = 'INSERT INTO user(username, password, mobile) VALUES(?, ?, ?)'
         c.execute(insert, [(self.n_username.get()), (self.n_password.get()), (self.n_mobile.get())])
         db.commit()

         ms.showinfo('Success!', 'Account Created!')
         self.log()
      else:
         ms.showerror('Error!', 'Please Enter the details.')

   def consignment(self):
      try:
         with sqlite3.connect('Akash5.db') as db:
            c = db.cursor()

         find_user = ('SELECT * FROM user WHERE mobile= ?')
         c.execute(find_user, [(self.mobile11.get())])
         result = c.fetchall()

         if result:
            self.track()
            self.crff.pack_forget()
            self.head['text'] = self.username.get() + '\n Your Product Details'

            # Get the latest value of destination before packing the frame
            destination_value = self.destination.get()

            # Update product details in consi frame
            self.consi.pack()
            for widget in self.consi.winfo_children():
               widget.destroy()  # Clear previous widgets in consi frame

               Label(self.consi, text='Product ID:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
               Label(self.consi, text=random.randint(565154, 99994216), font=('Arial', 13), pady=5, padx=5, fg="white", bg="black").grid(row=0, column=1)

               Label(self.consi, text='Product Name:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
               Label(self.consi, text=self.selected_product.get(), font=('Arial', 13), pady=5, padx=5, fg="white", bg="black").grid(row=1, column=1)

               Label(self.consi, text='Destination:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
               Label(self.consi, text=destination_value, font=('Arial', 13), pady=5, padx=5, fg="white", bg="black").grid(row=2, column=1)

               Label(self.consi, text='Product Status: Pending', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(row=3, column=1)

               Button(self.consi, text='Back', bd=2, font=('Arial', 13), padx=6, pady=6, command=self.track1, bg="gray").grid(row=4, column=0)
         else:
            ms.showerror('Oops!', 'Mobile Number Not Found.')
      except:
         ms.showerror('Oops!', 'Mobile Number Not Found.')

   def track1(self):
      self.consi.pack_forget()
      self.head['text'] = self.username.get() + '\n Track your Product'
      self.crff.pack()

   def log(self):
      self.username.set('')
      self.password.set('')
      self.crf.pack_forget()
      self.head['text'] = 'Login'
      self.logf.pack()

   def cr(self):
      self.n_username.set('')
      self.n_password.set('')
      self.logf.pack_forget()
      self.head['text'] = 'Create Account'
      self.crf.pack()

   def track(self):
      self.logf.pack_forget()
      self.head['text'] = self.username.get() + '\n Track your Product'
      self.crff.pack()

   def widgets(self):
      self.head = Label(self.master, text='LOGIN', font=('Arial', 20), pady=10, fg="white", bg="black")
      self.head.pack()

      self.logf = Frame(self.master, padx=10, pady=10, bg="black")

      Label(self.logf, text='Username:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
      Entry(self.logf, textvariable=self.username, bd=3, font=('Arial', 15)).grid(row=0, column=1)
      Label(self.logf, text='Password:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
      Entry(self.logf, textvariable=self.password, bd=3, font=('Arial', 15), show='*').grid(row=1, column=1)
      Button(self.logf, text=' Login ', bd=2, font=('Arial', 13), padx=6, pady=6, command=self.login, bg="gray").grid(row=8, column=0)
      Button(self.logf, text=' New user ', bd=2, font=('Arial', 13), padx=6, pady=6, command=self.cr, bg="gray").grid(row=8, column=1)

      self.logf.pack()

      self.crf = Frame(self.master, padx=10, pady=10, bg="black")
      Label(self.crf, text='Username:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
      Entry(self.crf, textvariable=self.n_username, bd=3, font=('Arial', 15)).grid(row=0, column=1)

      Label(self.crf, text='Password:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
      Entry(self.crf, textvariable=self.n_password, bd=3, font=('Arial', 15), show='*').grid(row=1, column=1)

      Label(self.crf, text='Mobile No.:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
      Entry(self.crf, textvariable=self.n_mobile, bd=3, font=('Arial', 15)).grid(row=5, column=1)

      Button(self.crf, text='Create Account', bd=2, font=('Arial', 13), padx=6, pady=6, command=self.new_user, bg="gray").grid(row=11, column=0)
      Button(self.crf, text='Go to Login', bd=2, font=('Arial', 13), padx=6, pady=6, command=self.log, bg="gray").grid(row=11, column=1)

      self.crff = Frame(self.master, padx=10, pady=10, bg="black")
      Label(self.crff, text='Consignment No:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
      Entry(self.crff, bd=3, font=('Arial', 15)).grid(row=0, column=1)
      Label(self.crff, text='Mobile no:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
      Entry(self.crff, bd=3, textvariable=self.mobile11, font=('Arial', 15)).grid(row=1, column=1)

      Label(self.crff, text="Select Product:", font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
      self.selected_product.set("Bag")
      products = ["Bag", "Colgate", "Shoe", "Redmi 2", "Jeans", "Mac", "Ipad", "Pen", "Book", "Shirt"]
      product_menu = ttk.Combobox(self.crff, textvariable=self.selected_product, values=products, font=('Arial', 13))
      product_menu.grid(row=2, column=1)

      Label(self.crff, text="Destination:", font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
      Entry(self.crff, textvariable=self.destination, bd=3, font=('Arial', 15)).grid(row=3, column=1)

      Button(self.crff, text='Track', bd=2, font=('Arial', 13), padx=6, pady=6, command=self.consignment, bg="gray").grid(row=4, column=0)

      self.consi = Frame(self.master, padx=10, pady=10, bg="black")
      Label(self.consi, text='Product ID:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
      Label(self.consi, text=random.randint(565154, 99994216), font=('Arial', 13), pady=5, padx=5, fg="white", bg="black").grid(row=0, column=1)

      Label(self.consi, text='Product Name:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
      Label(self.consi, text=self.selected_product.get(), font=('Arial', 13), pady=5, padx=5, fg="white", bg="black").grid(row=1, column=1)

      Label(self.consi, text='Destination:', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(sticky=W)
      Label(self.consi, text=self.destination.get(), font=('Arial', 13), pady=5, padx=5, fg="white", bg="black").grid(row=2, column=1)

      Label(self.consi, text='Product Status: Pending', font=('Arial', 15), pady=5, padx=5, fg="white", bg="black").grid(row=3, column=1)

      Button(self.consi, text='Back', bd=2, font=('Arial', 13), padx=6, pady=6, command=self.track1, bg="gray").grid(row=4, column=0)

if __name__ == '__main__':
   root = Tk()
   root.title('Track Consignment')
   root.geometry('800x450+300+300')
   root.configure(bg='black')  # Set background to black
   main(root)
   root.mainloop()

應用程式說明及輸出截圖

1. 登入介面

這是使用者啟動應用程式時看到的第一個介面。登入介面包括:使用者名稱和密碼輸入欄位,登入和新使用者註冊按鈕。

Courier Tracking Management System 1

2. 新使用者註冊介面

當用戶點選“新使用者”按鈕時,他們將進入註冊介面。我們建立了新使用者名稱“Rama DAS”並添加了密碼和手機號。此表單要求使用者提供:

Courier Tracking Management System 2

3. 快遞追蹤介面

使用者成功登入後,將進入貨物追蹤介面。他們可以輸入手機號查詢與其關聯的貨物。選擇產品並檢視其詳細資訊,例如目的地和狀態。

Courier Tracking Management System 3

4. 快遞詳情輸出

輸入手機號和產品後,系統將顯示快遞詳情,例如:產品ID(隨機生成)、產品名稱、目的地、狀態(預設為待處理)。

Courier Tracking Management System 4

程式碼說明

  • 匯入庫 - 指令碼首先匯入一些模組,主要用於Tkinter中的GUI開發,sqlite3中的資料庫操作以及random中的隨機數獲取。
  • 資料庫設定 - 它建立一個名為“Akash5.db”的新SQLite資料庫,如果不存在,它還會設定使用者表,用於儲存使用者資訊,例如憑據和/或手機號。
  • 類定義 - 這是一個主類,包含所有應用程式邏輯、資料庫連線和GUI管理。
  • 初始化 - 在__init__方法中,類建立StringVar變數,用於儲存使用者的輸入和產品詳細資訊。
  • 登入方法 - 登入方法檢查使用者輸入與資料庫中儲存的資料是否一致。如果找到,它將呼叫track()方法;如果沒有找到,則顯示錯誤訊息。
  • 新使用者方法 - 稱為new_user的方法負責建立帳戶。它首先驗證給定的使用者名稱是否在資料庫中可用,然後為新使用者建立一個新條目。
  • 貨物追蹤方法 - 在此方法中,使用者可以透過輸入手機號作為程式碼來追蹤貨物。如果找到手機號,則顯示貨物資訊。
  • Track1 方法 - 透過這種方式,貨物詳細資訊框架被最小化,而產品追蹤介面出現在螢幕上。
  • Log 方法 - log方法清除登入文字欄位並切換到登入介面。
  • Cr 方法 - cr方法清除註冊欄位並轉到帳戶建立螢幕。
  • Track 方法 - 此方法將GUI切換到貨物追蹤框架。
  • Widgets 方法 - 此方法顯示整個GUI,包括登入、註冊、貨物追蹤和產品詳情框架。
  • 登入框架 - 它包含登入框架(logf),其中包含用於輸入使用者名稱和密碼的框,以及“登入”和“建立帳戶”按鈕。
  • 註冊框架 - 註冊框架 (crf) 包含使用者名稱、密碼和手機號,以及建立新帳戶和轉到登入的選項。
  • 貨物追蹤框架 - 在貨物追蹤框架 (crff) 中,有一些欄位,例如貨物編號、用於識別客戶的手機號和產品選擇,以及用於追蹤貨物的目的地貨物按鈕。
  • 貨物詳情框架 - 貨物詳情框架 (consi) 顯示貨物的詳細資訊,包括產品的ID、名稱和目的地。
  • 隨機產品ID - randint() 方法為貨物詳情選擇一個隨機產品ID。
  • 產品選擇 - 對於允許使用者選擇產品的欄位,這裡使用的是下拉列表(藉助ttk.combobox)。
  • 錯誤處理 - 使用最簡單的異常處理形式,其中使用訊息框顯示無效輸入或未找到手機號的錯誤訊息。
  • 主執行 - 指令碼是第一個TI-Kinter指令碼,它透過提供標題和大小建立了一個GUI視窗,並透過建立主類的例項來啟動應用程式。
python_reference.htm
廣告