Python: tkinter グラフィカル インターフェイス アドレス帳 + txt テキスト ストレージ データ

1実験の目的と要件

実験の目的: 実用的な小さなアドレス帳プログラムを設計すること

実験的要件: 最後のアドレス帳をファイルに書き込んで保存する必要があります。

2実験内容

今回の実験内容は以下の通りです。

追加、クエリ、削除機能を備えた実用的な小さなアドレス帳プログラムを設計します。名前、出身地、電話番号1、電話番号2、メールアドレスで構成されており、文字と数字を組み合わせて記述することができます。電話番号は文字と数字で構成できます。

要件: 最後のアドレス帳が書き込まれるファイルに保存されている。

機能を実現します。

(1) システムはメニューモードで動作します

(2) 情報入力機能

(3) 情報閲覧機能

(4) 情報照会機能

(5) 情報変更機能

(6) システム終了機能

3 つの主な実験ステップ

(1) 必要なライブラリをインポートします。tkinter.messagebox はメッセージ ボックスの表示に使用され、json は JSON データの処理に使用され、os はファイル操作に使用され、tkinter は GUI インターフェイスの作成に使用されます。

(2) メインウィンドウの作成 root = tkinter.Tk() メインウィンドウを作成し、タイトルとサイズを設定します。

(3) スクロールバーの追加: 垂直スクロールバーを作成し、リスト ボックスに関連付けます。

(4) アドレス帳表示領域の作成: フレームを使用して、連絡先名、携帯電話番号などのアドレス帳情報を表示するためのフレームをメイン ウィンドウに作成します。

(5) アドレス帳ファイルを開く:カレントディレクトリにある「Address Book.txt」というファイルを開き、ファイルが存在しない場合は新規作成します。

(6) アドレス帳の連絡先情報を表示する関数 showinfo(): を定義します。

(7) ボタンと入力ボックスの作成: 連絡先の追加、連絡先の削除、連絡先の変更、連絡先の検索、終了ボタン、および連絡先の名前を入力するための入力ボックスが含まれます。

(8) ボタン イベントのバインド: 連絡先の追加、連絡先の削除、連絡先の変更、連絡先の検索、および終了ボタンのクリック イベントをそれぞれバインドし、ボタンがクリックされると対応する機能が実行されます。

(9) メインループの実行: root.mainloop() を使用してメインウィンドウのイベントループを実行し、ウィンドウがユーザーの操作に応答できるようにします。

4実験プロセス

4.1必要なモジュールをインポートする

tkinter.messagebox、json、os の 3 つのモジュールをインポートします。

tkinter.messageboxをインポートする

jsonをインポートする

私たちを輸入してください

tkinterをインポートする

の:

tkinter.messagebox モジュールは、GUI プログラムでメッセージ ボックスを表示するためのいくつかの関数を提供します。

json モジュールは、JSON データの読み取りと書き込みのためのいくつかの関数を提供します。

os モジュールは、オペレーティング システムと対話するためのいくつかの機能を提供します。

tkinter と呼ばれるモジュールもここでインポートされます。これは、Python に組み込まれたグラフィカル ユーザー インターフェイス (GUI) ツールキットであり、デスクトップ アプリケーションの開発時によく使用されます。

4.2メインウィンドウの作成

tkinter.Tk() を使用して root という名前のメイン ウィンドウを作成し、ウィンドウのタイトルを「連絡先」に、ウィンドウのサイズを 550x500 に設定します。

ルート = tkinter.Tk()

root.title('連絡先')

root.geometry("550x500")

このコードは、Python の tkinter モジュールを使用して、「root」という名前のウィンドウ (またはメイン ウィンドウと呼びます) を作成します。の:

tkinter.Tk() メソッドは、トップレベルのウィンドウ オブジェクトを作成し、それを変数 root に割り当てます。このウィンドウ オブジェクトは、他のすべてのウィジェットの親コンテナとして機能します。

root.title() メソッドは、メイン ウィンドウのタイトルを「連絡先」に設定します。

root.geometry() メソッドは、メイン ウィンドウのサイズを幅 550 ピクセル、高さ 500 ピクセルに設定するために使用されます。Python では、ウィンドウのサイズや位置などのパラメータを文字列で指定できます。たとえば、このコードの「550x500」という文字列は、ウィンドウの幅を 550 ピクセル、高さを 500 ピクセルに設定することを意味します。

4.3スクロールバーの追加

垂直スクロールバーを作成し、メイン ウィンドウの右側に配置します。

スクロールバー = tkinter.Scrollbar(root)

スクロールバー.pack(side=tkinter.RIGHT, fill=tkinter.Y)

このコードは、tkinter モジュールを使用して、ルート ウィンドウ (メイン ウィンドウ) に「scrollbar」と呼ばれるスクロールバー オブジェクトを作成します。の:

tkinter.Scrollbar() メソッドは、Scrollbar コンポーネント オブジェクトを作成し、それを変数スクロールバーに割り当てます。

スクロールバー.pack() メソッドは、スクロールバー ウィジェットをメイン ウィンドウの右側に配置し、その Y 軸を埋めるために使用されます。

ここでの Pack() メソッドは、tkinter で最も単純なレイアウト マネージャーです。GUI 開発でよく使用されます。ウィジェットをサイズに合わせて調整したり、一緒に配置したりできますが、達成できるのは比較的単純なレイアウト要件のみです。より柔軟で高度なレイアウト制御が必要な場合は、grid() や place() などの他のレイアウト マネージャーを使用できます。

4.4連絡先リストボックスの作成

連絡先リスト ボックスを保持するフレーム Frame_info を作成します。フレーム内にリストボックス リストボックスを作成し、垂直スクロールバーをリストボックスにバインドします。

Frame_info = tkinter.Frame(ルート、高さ=150、幅=180)

Frame_info.place(x=40, y=80)

listbox = tkinter.Listbox(Frame_info, yscrollcommand=scrollbar.set, font=('宋体', 15))

listbox.grid(row=2、column=0、columnspan=5、sticky=tkinter.NSEW)

スクロールバー.config(command=listbox.yview)

このコードは、tkinter モジュールを使用して、ルート ウィンドウ (メイン ウィンドウ) に「Frame_info」という名前のフレーム オブジェクトと「listbox」という名前のリストボックス オブジェクトを作成し、メイン ウィンドウの指定された位置に配置します。の:

tkinter.Frame() メソッドは、Frame コンポーネント オブジェクトを作成し、それを変数 Frame_info に割り当てます。このコンポーネントは通常、他のウィジェットのレイアウトをより適切に管理するためのコンテナとして使用されます。

Frame_info.place() メソッドは、メイン ウィンドウの指定された位置 (x=40、y=80) に Frame_info コンポーネントを配置するために使用されます。

listbox = tkinter.Listbox(Frame_info,...) メソッドは、Listbox コンポーネント オブジェクトを作成し、それを変数 listbox に割り当てます。このコンポーネントは、スクロール可能なテキスト リストを表示するために使用されます。

listbox.grid(...) メソッドの設定パラメータは、Frame_info フレーム内のリストボックス オブジェクトのオフセットやサイズなどの表示プロパティを設定するために使用されます。

スクロールバーt.config(command=listbox.yview)は、関連付けられたスクロールバーと対応するテキストリストを実現するために使用されます。

ここで、sticky=tkinter.NSEW は、コンポーネントがサイズに適応してグリッド全体を占めるように、フレーム内のスペースを拡張して埋めることができるようにすることを意味します。Sticky が指定されていない場合、必要最小限のスペースのみを占有し、適応的に拡張することはできません。

4.5アドレス帳ファイルを開いて連絡先情報を表示します。

ファイル = open(" Contacts.txt"、モード = 'a'、エンコーディング = 'utf-8')

file.close()

これにより、「Contacts.txt」という名前のファイルが追加モードで開かれ、存在しない場合は空のファイルが作成されます。その後、すぐにファイルを閉じます。

def showinfo():

    listbox.delete(0, tkinter.END)

    ファイル = open(" Contacts.txt"、モード = 'r'、エンコーディング = 'utf-8')

    len(file.read()) != 0の場合:

        ファイル.seek(0, 0)

        file_data = file.read()

        split_info = file_data.split('\n')

        split_info.remove(split_info[len(split_info) - 1])

        名前_リ = []

        all_info_li = []

        私にとっては、split_info:

            dict_info = json.loads(i.replace("\'", '\"'))

            all_info_li.append(dict_info)

            listbox.insert(tkinter.END, dict_info['名前'] + ' ' + dict_info['携帯番号 1'] + ' ' + dict_info['携帯番号 2'] + ' ' +

                           dict_info['メールアドレス'] + ' ' + dict_info[' アドレス'])

file.close()

showinfo() 関数は、連絡先情報を表示するために定義されています。この関数は、まずリストボックスの内容をクリアし、次にアドレス帳ファイルを開いてその中の情報を読み取ります。JSON 文字列を解析して、各連絡先の情報を all_info_li リストに追加し、結合後に名前とその他の情報をリスト ボックスに挿入します。最後にファイルを閉じます。の:

listbox.delete(0, tkinter.END) メソッドは、前のリストボックス内のすべてのデータをクリアするために使用されます。

file = open("Address Book.txt", mode='r',coding='utf-8') は、「Address Book.txt」という名前のファイルを開き、ファイル オブジェクトを変数 file に割り当てます。mode='r' はファイルを読み取り専用モードで開くことを意味し、encoding='utf-8' はファイルのエンコード形式を指定します。

len(file.read()) != 0 は、現在のファイルが空かどうかを判断するために使用されます。空でない場合は、表示する必要のあるアドレス帳情報があることを意味します。

file.seek(0, 0) は、ファイルポインタをファイルの先頭に移動することを意味します。

file_data = file.read() は、ファイル全体を文字列変数 file_data に読み取ります。

split_info = file_data.split('\n') は、split() メソッドを使用して、改行文字に従ってファイルの内容を部分文字列に分割し、リスト split_info を返します。

split_info.remove(split_info[len(split_info) - 1]) は、split_info リストの最後の空の文字列要素を削除します。

for ループでは、リスト split_info 内の各部分文字列 i が 1 つずつ調べられます。まず json.loads() メソッドを使用して文字列内の JSON 形式データを解析し、それをリスト all_info_li に追加して保存します。次に、解析したアドレス帳データの情報を、指定された形式に従ってリストボックスに挿入します。

最後に、ファイル ハンドル リソースのリークを防ぐために、忘れずにファイルを閉じてください。

4.6連絡先機能の追加

def add_def():

    add_info = {'名前': '', '携帯番号 1': '', '携帯番号 2': '', 'メールアドレス': '', '住所': ''}

    add_info['姓名'] = name_input.get()

    if add_info[' name'] == '':

        tkinter.messagebox.showinfo('プロンプト', '名前を入力してください!')

        戻る

    add_info['携帯電話番号 1'] = pho_input.get()

    add_info['携帯電話番号 2'] = pho_input2.get()

    add_info['メール'] = email_input.get()

    add_info['地址'] = address_input.get()

    ファイルとしてopen(" Contacts.txt", 'a+', encoding='utf-8') を使用します:

        file.write(str(add_info) + '\n')

    showinfo()

    name_input.delete(0, tkinter.END)

    pho_input.delete(0, tkinter.END)

    pho_input2.delete(0, tkinter.END)

    email_input.delete(0, tkinter.END)

address_input.delete(0, tkinter.END)

add_def() 関数は連絡先を追加するために定義されています。この関数は、まず空の連絡先情報辞書 add_info を作成し、次に連絡先の名前、携帯電話番号、電子メール アドレス、および住所を入力ボックスから取得して、辞書に入力します。次に、連絡先情報を文字列形式でアドレス帳ファイルに書き込みます。最後に、showinfo() 関数を呼び出してリスト ボックスの内容を更新し、入力ボックスの内容をクリアします。の:

add_info = {'名前': '', '携帯電話番号 1': '', '携帯電話番号 2': '', '電子メール': '', 'アドレス': ''} 空の辞書 add_info を作成します。

add_info['name'] = name_input.get() グラフィカルインターフェイスから名前入力ボックスの値を取得し、辞書 add_info の「name」フィールドに保存します。

if add_info['name'] == '': 名前が空かどうかを判断するために使用されます。空の場合は、プロンプト ボックスが表示され、機能が終了します。

add_info['電話番号 1'] = pho_input.get() グラフィカル インターフェイスから電話番号 1 入力ボックスの値を取得し、辞書 add_info の「電話番号 1」フィールドに保存します。

add_info['電話番号 2'] = pho_input2.get() グラフィカル インターフェイスから電話番号 2 入力ボックスの値を取得し、辞書 add_info の「電話番号 2」フィールドに保存します。

add_info['email'] = email_input.get() グラフィカル インターフェイスから電子メール入力ボックスの値を取得し、辞書 add_info の「電子メール」フィールドに保存します。

add_info['address'] = address_input.get() グラフィカル インターフェイスからアドレス入力ボックスの値を取得し、辞書 add_info の「address」フィールドに保存します。

with open("Address Book.txt", 'a+', encoding='utf-8') as file: "Address Book.txt" という名前のファイルを開き、ファイル オブジェクトを変数 file に割り当てます。mode='a+' は、ファイルが追加モードで開かれ、指定されたファイルのエンコード形式が utf-8 であることを示します。

file.write(str(add_info) + '\n') は、辞書 add_info を文字列としてファイルに書き込み、最後に改行を追加します。

showinfo() は、「showinfo()」関数を呼び出して、アドレス帳のデータ表示部分を更新します。

最後に、各入力ボックスのデータをクリアし、ユーザーの入力を待ち続けます。

4.7連絡先削除機能

def del_def():

    selected_item = listbox.curselection()

    selected_item でない場合:

        tkinter.messagebox.showinfo('プロンプト', '削除する連絡先を選択してください!')

        戻る

    それ以外:

        ファイル = open(" Contacts.txt"、モード = 'r'、エンコーディング = 'utf-8')

        read_data = file.readlines()

        file.close()

        選択されたインデックス = 選択された項目[0]

        del read_data[selected_index]

        ファイル = open(" Contacts.txt"、モード = 'w'、エンコーディング = 'utf-8')

        file.writelines(read_data)

        file.close()

        showinfo()

del_def() 関数は、選択した連絡先を削除するために定義されています。まず連絡先が選択されているかどうかを確認します。選択されていない場合は、プロンプト ボックスが表示されます。選択した連絡先がある場合は、アドレス帳ファイルを開き、その内容を 1 行ずつ読み取ります。選択した連絡先のインデックスを見つけたら、対応する行を削除し、残りの内容をファイルに再書き込みします。最後に、showinfo() 関数を呼び出してリスト ボックスの内容を更新します。の:

selected_item = listbox.curselection() ユーザーがグラフィカル インターフェイスで選択した連絡先を「curselection()」メソッドを通じて取得し、変数 selected_item に保存します。

選択されていない場合: selected_item: ユーザーが削除する連絡先を選択したかどうかを判断します。選択がない場合は、プロンプト ボックスが表示され、機能が終了します。

file = open("Address Book.txt", mode='r',coding='utf-8') は、「Address Book.txt」という名前のファイルを開き、ファイル オブジェクトを変数 file に割り当てます。mode='r' は、ファイルが読み取り専用モードで開かれ、指定されたファイルのエンコード形式が utf-8 であることを示します。これを行う前に、ファイルが作成されていることを確認する必要があることに注意してください。

read_data = file.readlines() は、ファイル内のすべての行を読み取り、リスト read_data に保存します。

file.close() はファイルを閉じます。

selected_index = selected_item[0] ユーザーが選択した連絡先のインデックス値を取得し、変数 selected_index に保存します。

del read_data[selected_index] ユーザーが選択した連絡先のデータをリスト read_data から削除します。

file = open("Contacts.txt", mode='w',coding='utf-8') ファイルを書き込みモードで再度開き、ファイル オブジェクトを変数 file に割り当てます。mode='w' はファイルを上書きモードで開くことを意味し、指定されたファイルのエンコード形式は utf-8 です。

file.writelines(read_data) は、処理されたすべてのデータをファイルに再書き込みします。

file.close() はファイルを閉じます。

showinfo() は、「showinfo()」関数を呼び出して、アドレス帳のデータ表示部分を更新します。

4.8接点機能の変更

def update_def():

    selected_item = listbox.curselection()

    selected_item でない場合:

        tkinter.messagebox.showinfo('プロンプト', '変更する連絡先を選択してください!')

        戻る

    それ以外:

        ファイル = open(" Contacts.txt"、モード = 'r'、エンコーディング = 'utf-8')

        read_data = file.readlines()

        file.close()

        選択されたインデックス = 選択された項目[0]

        selected_info = json.loads(read_data[selected_index].replace("\'", '\"'))

        name_input.insert(0, selected_info['姓名'])

        pho_input.insert(0, selected_info['携帯電話番号 1'])

        pho_input2.insert(0, selected_info['携帯番号 2'])

        email_input.insert(0, selected_info[' email'])

        address_input.insert(0, selected_info['地址'])

        del read_data[selected_index]

        ファイル = open(" Contacts.txt"、モード = 'w'、エンコーディング = 'utf-8')

        file.writelines(read_data)

        file.close()

        showinfo()

update_def() 関数は、選択した連絡先を変更するために定義されています。まず連絡先が選択されているかどうかを確認します。選択されていない場合は、プロンプト ボックスが表示されます。選択した連絡先がある場合は、アドレス帳ファイルを開き、その内容を 1 行ずつ読み取ります。選択した連絡先のインデックスを見つけたら、その情報を解析して辞書に入れ、対応する値を対応する入力ボックスに入力します。次に、選択した連絡先情報を削除し、残りの内容をファイルに再度書き込みます。最後に、showinfo() 関数を呼び出してリスト ボックスの内容を更新します。

このコードでは、アドレス帳情報を変更する機能を実装する「update_def()」という関数を定義しています。の:

selected_item = listbox.curselection() ユーザーがグラフィカル インターフェイスで選択した連絡先を「curselection()」メソッドを通じて取得し、変数 selected_item に保存します。

selected_item でない場合: ユーザーが変更する連絡先を選択したかどうかを判断します。選択がない場合は、プロンプト ボックスが表示され、機能が終了します。

file = open("Address Book.txt", mode='r',coding='utf-8') は、「Address Book.txt」という名前のファイルを開き、ファイル オブジェクトを変数 file に割り当てます。mode='r' は、ファイルが読み取り専用モードで開かれ、指定されたファイルのエンコード形式が utf-8 であることを示します。これを行う前に、ファイルが作成されていることを確認する必要があることに注意してください。

read_data = file.readlines() は、ファイル内のすべての行を読み取り、リスト read_data に保存します。

file.close() はファイルを閉じます。

selected_index = selected_item[0] ユーザーが選択した連絡先のインデックス値を取得し、変数 selected_index に保存します。

selected_info= json.loads(read_data[selected_index].replace("\'", '\"')) read_dataからユーザーが選択した連絡先情報を取得し、辞書形式のデータに変換します(シングルクォーテーションを使用しているため、最初に二重引用符に置き換えてください)。

name_input.insert(0, selected_info['name']) 選択した連絡先の名前情報を対応するテキスト ボックスに表示します。

pho_input.insert(0, selected_info['電話番号 1']) は、選択した連絡先の電話番号 1 の情報を対応するテキスト ボックスに表示します。

pho_input2.insert(0, selected_info['電話番号 2']) は、選択した連絡先の電話番号 2 の情報を対応するテキスト ボックスに表示します。

email_input.insert(0, selected_info['email']) は、選択した連絡先の電子メール情報を対応するテキスト ボックスに表示します。

address_input.insert(0, selected_info['address']) 選択した連絡先のアドレス情報を対応するテキスト ボックスに表示します。

del read_data[selected_index] ユーザーが選択した連絡先のデータをリスト read_data から削除します。

file = open("Contacts.txt", mode='w',coding='utf-8') ファイルを書き込みモードで再度開き、ファイル オブジェクトを変数 file に割り当てます。mode='w' はファイルを上書きモードで開くことを意味し、指定されたファイルのエンコード形式は utf-8 です。

file.writelines(read_data) は、処理されたすべてのデータをファイルに再書き込みします。

file.close() はファイルを閉じます。

showinfo() は、「showinfo()」関数を呼び出して、アドレス帳のデータ表示部分を更新します。

4.9各コンポーネントの作成

name_label = tkinter.Label(root, text=' name:', font=('Arial', 15))

name_label.place(x=40, y=280)

name_input = tkinter.Entry(root, font=('宋体', 15))

name_input.place(x=90, y=280)

pho_label = tkinter.Label(root, text='携帯電話番号1:', font=('宋体', 15))

pho_label.place(x=10, y=330)

pho_input = tkinter.Entry(root, font=('宋体', 15))

pho_input.place(x=90, y=330)

pho_label2 = tkinter.Label(root, text='携帯電話番号 2:', font=('宋体', 15))

pho_label2.place(x=10, y=380)

pho_input2 = tkinter.Entry(root, font=(' Arial', 15))

pho_input2.place(x=90, y=380)

email_label = tkinter.Label(root, text='電子メール:', font=('Arial', 15))

email_label.place(x=40, y=430)

email_input = tkinter.Entry(root, font=(' Arial', 15))

email_input.place(x=90, y=430)

address_label = tkinter.Label(root, text='アドレス:', font=('Arial', 15))

address_label.place(x=40, y=480)

address_input = tkinter.Entry(root, font=('宋体', 15))

address_input.place(x=90, y=480)

add_button = tkinter.Button(root, text=' Add', font=('Arial', 15), command=add_def)

add_button.place(x=420, y=280)

del_button = tkinter.Button(root, text='削除', font=('Arial', 15), command=del_def)

del_button.place(x=420, y=330)

update_button = tkinter.Button(root, text=' modify', font=('宋体', 15), command=update_def)

update_button.place(x=420, y=380)

quit_button = tkinter.Button(root, text=' quit', font=('宋体', 15), command=root.quit)

quit_button.place(x=420, y=430)

ラベル、入力ボックス、ボタンなどのさまざまな GUI コンポーネントを作成し、place() メソッドを使用してメイン ウィンドウの指定した位置に配置します。の:

Label は、テキスト コンテンツを表示するためのテキスト ラベルを作成します。

Entry テキストコンテンツを入力および表示するためのテキストボックスを作成します。

Button 対応するアクションをトリガーするボタンを作成します。

place(x, y) メソッドは、インターフェイス上のコンポーネントの位置座標を設定するために使用されます。

具体地:

name_label は、「name」という名前のテキスト ラベルを作成し、位置 (40, 280) の座標に配置します。

name_input は、名前を入力するためのテキストボックスを作成し、位置 (90, 280) の座標に配置します。

pho_label は、「電話番号 1」というテキスト ラベルを作成し、それを位置の座標 (10, 330) に配置します。

pho_input は、携帯電話番号を入力するためのテキストボックスを作成し、それを位置座標 (90, 330) に配置します。

pho_label2 は、「電話番号 2」というテキスト ラベルを作成し、位置の座標 (10, 380) に配置します。

pho_input2 は、携帯電話番号を入力するための別のテキストボックスを作成し、それを位置座標 (90, 380) に配置します。

email_label は、「email」というテキスト ラベルを作成し、位置 (40, 430) の座標に配置します。

email_input は、電子メールを入力するためのテキストボックスを作成し、位置 (90, 430) の座標に配置します。

address_label は、「address」という名前のテキスト ラベルを作成し、それを位置の座標 (40, 480) に配置します。

address_input は、住所を入力するためのテキストボックスを作成し、それを位置の座標 (90, 480) に配置します。

次に 4 つのボタンがあります。

add_button は、「追加」という名前のボタンを作成し、位置 (420, 280) の座標に配置します。このボタンは、add_def() 関数をトリガーして、連絡先情報を追加する機能を実現します。

del_button は、「削除」という名前のボタンを作成し、位置 (420, 330) の座標に配置します。このボタンは、del_def() 関数をトリガーして、連絡先情報を削除する機能を実現します。

update_button は「Update」というボタンを作成し、位置 (420, 380) の座標に配置します。このボタンは、update_def() 関数をトリガーして、連絡先情報を変更する機能を実現します。

quit_button は、「追加」というボタンを作成し、それを位置 (420, 430) の座標に配置します。このボタンは終了機能を実装します。

4.10連絡先情報の表示

showinfo()

showinfo() 関数を呼び出して、初期化中に既存の連絡先情報を表示します。

4.11メインループの実行

root.mainloop()

GUI アプリケーションのメイン ループは、mainloop() メソッドを呼び出すことによって開始され、ユーザー対話イベントが発生するのを待ちます。

上記はコードの詳細な実装プロセスです。シンプルなアドレス帳アプリケーションは、GUI ウィンドウの作成、ファイルの読み取り、連絡先の追加、削除、変更によって実装されます。ユーザーはインターフェース上で連絡先情報を入力し、ボタン操作で連絡先の追加、削除、変更、問い合わせを行うことができます。

【完全なコード】

import tkinter.messagebox
import json
import os
import tkinter

root = tkinter.Tk()
root.title('通讯录')
root.geometry("550x500")

# 添加滚动条
scrollbar = tkinter.Scrollbar(root)
scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)

Frame_info = tkinter.Frame(root, height=150, width=180)
Frame_info.place(x=40, y=80)#滚动框位置

# 绑定滚动条和列表
listbox = tkinter.Listbox(Frame_info, yscrollcommand=scrollbar.set, font=('宋体', 15))
listbox.grid(row=2, column=0, columnspan=5, sticky=tkinter.NSEW)

# 设置滚动条和列表的关系
scrollbar.config(command=listbox.yview)
#

#标题属性的另一个设置方法
# name_label = tkinter.Label(Frame_info, text="名字", font=('宋体', 15))
# name_label.grid(row=1, column=0)
# phone_label = tkinter.Label(Frame_info, text="手机号1", font=('宋体', 15))
# phone_label.grid(row=1, column=1)
# phone_label = tkinter.Label(Frame_info, text="手机号2", font=('宋体', 15))
# phone_label.grid(row=1, column=2)
# mail_label = tkinter.Label(Frame_info, text="邮箱", font=('宋体', 15))
# mail_label.grid(row=1, column=3)
# address_label = tkinter.Label(Frame_info, text="地址", font=('宋体', 15))
# address_label.grid(row=1, column=4)


file = open("通讯录.txt", mode='a', encoding='utf-8')
file.close()

def showinfo():
    # 清空列表
    listbox.delete(0, tkinter.END)

    file = open("通讯录.txt", mode='r', encoding='utf-8')
    if len(file.read()) != 0:
        file.seek(0, 0)
        file_data = file.read()
        split_info = file_data.split('\n')
        split_info.remove(split_info[len(split_info) - 1])
        name_li = []  # 用于存储联系人姓名的列表
        all_info_li = []  # 用于存储所有信息的列表
        for i in split_info:
            dict_info = json.loads(i.replace("\'", '\"'))
            all_info_li.append(dict_info)
            # 添加到列表中
            listbox.insert(tkinter.END, dict_info['姓名'] + ' ' + dict_info['手机号1'] + ' ' + dict_info['手机号2'] + ' ' +
                           dict_info['邮箱'] + ' ' + dict_info['地址'])
            row_count = 0
            column_count = 0

        # for i in all_info_li:
        #     # row_count += 1
        #     column_count += 1

            # for title, info_value in person_info.items():
            #     tktest = tkinter.Label(Frame_info, text=info_value, font=('宋体', 15, 'bold'))
            #     tktest.grid(row=row_count, column=column_count)
            #     column_count += 1
            # row_count += 1
            tktest = tkinter.Label(Frame_info, text=" " *42, font=('宋体', 15, 'bold'))#设置滚动框显示的宽度
            tktest.grid(row=row_count, column=column_count)


showinfo()

# 添加
def add_def(event):
    def add_man(event):
        name = name_new.get()
        phone1 = phone_new1.get()
        phone2 = phone_new2.get()
        mail = mail_new.get()
        address = adr_new.get()
        if name == "" or phone1 == " " or phone2 == " " or mail == " " or address == " ":
            tkinter.messagebox.showerror('错误', '所填信息都不能为空')
        else:
            card_dict = {"姓名": name, "手机号1": phone1, "手机号2": phone2,
                         "邮箱": mail, "地址": address}
            f = open("通讯录.txt", mode='a+', encoding='utf-8')
            f.write(str(card_dict) + '\n')
            f.close()
            tkinter.messagebox.showinfo('消息提示框', f'添加“{name}“为联系人成功!')
            showinfo()
            window_add.destroy()



    # 弹出框
    window_add = tkinter.Toplevel(root)
    window_add.geometry('300x250')
    # 姓名
    name_new = tkinter.StringVar()
    tkinter.Label(window_add, text='新联系人姓      名:').place(x=10, y=10)
    tkinter.Entry(window_add, textvariable=name_new).place(x=130, y=10)
    # 手机号1
    phone_new1 = tkinter.StringVar()
    tkinter.Label(window_add, text='新联系人手机号1:').place(x=10, y=50)
    tkinter.Entry(window_add, textvariable=phone_new1).place(x=130, y=50)
    # 手机号2
    phone_new2 = tkinter.StringVar()
    tkinter.Label(window_add, text='新联系人手机号2:').place(x=10, y=90)
    tkinter.Entry(window_add, textvariable=phone_new2).place(x=130, y=90)
    # 邮箱
    mail_new = tkinter.StringVar()
    tkinter.Label(window_add, text='新联系人邮      箱:').place(x=10, y=130)
    tkinter.Entry(window_add, textvariable=mail_new).place(x=130, y=130)
    # 地址
    adr_new = tkinter.StringVar()
    tkinter.Label(window_add, text='新联系人地      址:').place(x=10, y=170)
    tkinter.Entry(window_add, textvariable=adr_new).place(x=130, y=170)
    # 确认
    confirm_button = tkinter.Button(window_add, text='确认添加', font=('宋体', 15))
    confirm_button.bind("<Button-1>", add_man)
    confirm_button.place(x=100, y=200)

# 删除
def del_def(event):
    name = man_name.get()
    file = open("通讯录.txt", mode='r+', encoding='utf-8')
    if len(file.read()) != 0:
        file.seek(0, 0)
        file_data = file.read()
        split_info = file_data.split('\n')
        split_info.remove(split_info[len(split_info) - 1])
        name_li = []
        all_info_li = []
        for i in split_info:
            dict_info = json.loads(i.replace("\'", '\"'))
            all_info_li.append(dict_info)
            name_li.append(dict_info['姓名'])
        if name in name_li:
            通讯录_copy = open('通讯录_copy.txt', mode='w+', encoding="utf-8")
            for person_info in all_info_li:
                if name not in str(person_info):
                    通讯录_copy.write(str(person_info) + '\n')
            通讯录_copy.close()
            file.close()
            os.rename('通讯录.txt', '通讯录_del.txt')
            os.rename('通讯录_copy.txt', '通讯录.txt')
            os.remove('通讯录_del.txt')
            tkinter.messagebox.showinfo('消息提示', f'删除“{name}“成功!')
            showinfo()
        else:
            tkinter.messagebox.showinfo('消息提示', '查无此人!')


# 修改
def update_def(event):
    def update_man(event):
        name = name_new.get()
        phone1 = phone_new1.get()
        phone2 = phone_new2.get()
        mail = mail_new.get()
        address = address_new.get()
        if name != "" and phone1 != "" and phone2 != "" and mail != "" and address != "":
            通讯录_copy = open('通讯录_copy.txt', mode='w', encoding="utf-8")
            # 将数据封装到字典中
            card_dict = {"姓名": name, "手机号1": phone1, "手机号2": phone2,
                         "邮箱": mail, "地址": address}
            for person_info in all_info_li:
                if name_old in str(person_info):
                    person_info = str(card_dict)
                通讯录_copy.write(str(person_info) + '\n')
            通讯录_copy.close()
            file.close()
            os.rename('通讯录.txt', '通讯录_del.txt')
            os.rename('通讯录_copy.txt', '通讯录.txt')
            os.remove('通讯录_del.txt')
            tkinter.messagebox.showinfo('消息提示框', '更新成功!')
            showinfo()
        else:
            tkinter.messagebox.showinfo('消息提示框', '请输入正确信息,或输入完整信息')
    name_old = man_name.get()
    file = open("通讯录.txt", mode='r+', encoding='utf-8')
    if len(file.read()) != 0:
        file.seek(0, 0)
        file_data = file.read()
        split_info = file_data.split('\n')
        split_info.remove(split_info[len(split_info) - 1])
        name_li = []
        all_info_li = []
        for i in split_info:
            dict_info = json.loads(i.replace("\'", '\"'))
            all_info_li.append(dict_info)
            name_li.append(dict_info['姓名'])
        if name_old in name_li:
            window_update = tkinter.Toplevel(root)
            window_update.geometry('280x200')
            # 输入更新的信息
            name_new = tkinter.StringVar()
            phone_new1 = tkinter.StringVar()
            phone_new2 = tkinter.StringVar()
            mail_new = tkinter.StringVar()
            address_new = tkinter.StringVar()
            # 输入更改后的信息
            tkinter.Label(window_update, text='姓      名:').place(x=20, y=0)
            tkinter.Entry(window_update, textvariable=name_new).place(x=90, y=0)
            tkinter.Label(window_update, text='手机号1:').place(x=20, y=30)
            tkinter.Entry(window_update, textvariable=phone_new1).place(x=90, y=30)
            tkinter.Label(window_update, text='手机号2:').place(x=20, y=60)
            tkinter.Entry(window_update, textvariable=phone_new2).place(x=90, y=60)
            tkinter.Label(window_update, text='邮      箱:').place(x=20, y=90)
            tkinter.Entry(window_update, textvariable=mail_new).place(x=90, y=90)
            tkinter.Label(window_update, text='地      址:').place(x=20, y=120)
            tkinter.Entry(window_update, textvariable=address_new).place(x=90, y=120)
            # 确认
            confirm_button = tkinter.Button(window_update, text='确认修改', font=('宋体', 15))
            confirm_button.bind("<Button-1>", update_man)
            confirm_button.place(x=100, y=150)
        else:
            tkinter.messagebox.showinfo('消息提示', '通讯录中查无此人')

# 查找
def find_def(event):
    name = man_name.get()
    file = open("通讯录.txt", mode='r+', encoding='utf-8')
    if len(file.read()) != 0:
        file.seek(0, 0)
        file_data = file.read()
        split_info = file_data.split('\n')
        split_info.remove(split_info[len(split_info) - 1])
        name_li = []
        all_info_li = []
        for i in split_info:
            dict_info = json.loads(i.replace("\'", '\"'))
            all_info_li.append(dict_info)
            name_li.append(dict_info['姓名'])
        if name in name_li:
            man_find = tkinter.Toplevel(root)
            man_find.geometry('400x140')
            for person_info in all_info_li:
                if name in str(person_info):
                    for title, info_value in person_info.items():
                        tem_text = title + ":" + info_value + " " *10
                        tktest = tkinter.Label(man_find, text=tem_text, font=('宋体', 15))
                        tktest.pack(side="top", anchor='w')
        else:
            tkinter.messagebox.showinfo('消息提示', '通讯录中查无此人')

# 退出
def over_def(event):
    root.destroy()

# 输入框
man_nametitle = tkinter.Label(root,text="请输入联系人姓名:", font=('宋体', 10)).place(x=40,y=358)#x为距离左侧距离
man_name = tkinter.StringVar()
tkinter.Entry(root, textvariable=man_name, width=28).place(x=160, y=355)#输入框位置

# 联系人名单标题
man_nametitle = tkinter.Label(root,text="联系人名单列表", font=('宋体', 20, 'bold')).place(x=180,y=35)
man_nametitle = tkinter.Label(root,text="-"*150,).place(x=0,y=10)

#属性标题
man_nametitle = tkinter.Label(root,text="姓名    手机号1    手机号2      邮箱   地址", font=('宋体', 15, 'bold')).place(x=44,y=75)
man_nametitle = tkinter.Label(root,text="-"*150,).place(x=0,y=10)
# 添加
button1 = tkinter.Button(root, text="添加联系人", width=10, height=2,font=('宋体', 15))
button1.place(x=40, y=400)
button1.bind('<Button-1>', add_def)

# 删除
button3 = tkinter.Button(root, text="删除联系人", width=10,height=2, font=('宋体', 15))
button3.place(x=280, y=400)
button3.bind('<Button-1>', del_def)

# 修改
button4 = tkinter.Button(root, text="修改联系人", width=10,height=2, font=('宋体', 15))
button4.place(x=160, y=400)
button4.bind('<Button-1>', update_def)

# 查找
button5 = tkinter.Button(root, text="查找联系人", width=10, font=('宋体', 15))
button5.place(x=398, y=350)
button5.bind('<Button-1>', find_def)

# 退出
button6 = tkinter.Button(root, text="退出", width=10, height=2, font=('宋体', 15))
button6.place(x=398, y=400)
button6.bind('<Button-1>', over_def)

root.mainloop()  # 显示主窗体

5実験結果

6実験の概要

今回の実験の設計プロセスはさまざまな紆余曲折を経たと言え、コード量は合計293行(コメント含む)とかなりの量になった。

このうち、ファイルの保存と読み取りの操作設計部分は、辞書操作を使用するため、保存と読み取りに特別な変換が必要で、関連するアルゴリズムは継続的なデバッグの後に最終的に正常に渡されます。

ビジュアルデザインのプロセスでは、ボタンやテキストボックスのレイアウト、関数の内部転送パラメータ、特殊な場合のプログラム処理、メニューのデザインなど、多くの要素が考慮されます。メニュー設計の過程で、大量のブログを検索したり、他の人のコードを読んだりして、位置パラメータを渡す設計方法を学び、それを今回の設計実験に応用して反映させました。インターフェースの設計過程において、Pythonでレイアウトを調整できる関数はpack()、grid()、place()の3つしかなく、関数を使用するには表示位置を制御するための異なるパラメータを入力する必要があるため、インターフェースをできるだけ美しくするために、長いレイアウトプロセスを経ましたが、ポップ内の各ボタンやテキストボックスのレイアウトを変更するなど、デバッグできない不備がいくつかあります。ウィンドウを開くと、まだ埋められない空白部分がいくつかあります。

全体的なプロセスには多少の浮き沈みがありますが、幸いなことに、私たちは既知の問題を解決するために最善を尽くしてきました。この設計実験では、レイアウトを設計するために tkinter モジュールを呼び出す私の能力が十分に発揮され、大幅な改善が見られましたが、同時に、Python 環境を使用してビジュアル デザインを行うのは確かに少し難しいこともわかりました。内部モジュールの機能を継続的に更新する必要がある デザイン レイアウト機能が使いやすく、利便性が十分ではありません。しかし、Python プログラミングの能力を最大限に発揮するために、壁を乗り越えたのは勝利とも言えるでしょう。

おすすめ

転載: blog.csdn.net/weixin_55988897/article/details/131161712