「Pythonでデスクトップアプリを作ろう 後編」 その14
「Pythonでデスクトップアプリを作ろう 後編」 その14# -*- coding: utf-8 -*-"""Created on Sun Jun 4 14:57:20 2023@author: mlupi""""""『日経ソフトウエア』2022年11月号(p.046~p.065)の特集記事 9月号の「特集2 Pythonでデスクトップアプリを作ろう 前編」に引き続いて、 11月号の「特集3 Pythonでデスクトップアプリを作ろう 後編」に挑戦中。なお、基礎については、当ブログの「Pythonことはじめ」などを参照してください。前回、「保存」ボタンが機能しませんでしたが、その原因が分かりました。打ち間違えでした。「保存ボタンがクリックされた時に呼び出される関数(def save(t_day):)」の引数「end-1c」の「1」(数字のいち)が、「l」(英小文字のエル)になっていたためでした。以下に、そのを訂正した「リスト3-2●「daily_memo.py」を掲載します。"""# 「Pythonでデスクトップアプリを作ろう 後編」 その14# 標準の「Tkinter」+「SQLite3」を使って# Part2 カレンダー型「メモアプリ」を作る(p.053~p.058)# ③ カレンダー型「メモアプリ」のプログラム(p.055~p.057)# ④ 「保存」ボタンがクリックされた時の処理(p.057)# ⑤ 「calender」モジュールを使う(p.057~p.058)#Python#Tkinter#SQLite3#日経ソフトウエア#デスクトップアプリ#データベース#データベースへの接続#Select文#データの抽出#Tkinter#Textウイジェット#Scrollウイジェット#Scrollbar関数#orientオプション#tk.VERTICAL#commandオプション#yview関数#yscrollcommandオプション#set関数#daily_memo.py#カレンダー型メモアプリ#「click関数」#「bind関数」を使って「click関数」と紐づけている#「insert関数」## 『日経ソフトウエア』2022年11月号(p.046~p.065)## 目次## Intro Python+Tkinter+SQLiteが一番手軽(p.046~p.047)## Part1 SQLite3の基本をマスターしよう(p.047~p.053)# ① データベースを作成する(p.047~p.048)# ② テーブルを作成する(p.048~p.049)# ③ 「INSERT INTO」文でデータを追加する(p.049~p.050)# ④ データベースやテーブルの削除(p.050)# ⑤ 「SELECT」文でデータを抽出する(p.050~p.051)# ⑥ 「LIKE」演算子であいまい検索を実現する(p.051~p.052)# ⑦ 「ORDER BY」句でデータをソートする(p.052~p.053)# Part2 カレンダー型「メモアプリ」を作る(p.053~p.058)# ① メモアプリのデータベースを作る(p.053p.054)# ② メモを入力・表示する機能(p.054~p.055)# ③ カレンダー型「メモアプリ」のプログラム(p.055~p.057)# ④ 「保存」ボタンがクリックされた時の処理(p.057)# ⑤ 「calender」モジュールを使う(p.057~p.058)# Part3 「蔵書管理アプリ」を作る(p.058~p.065)# ① 「Treeview」ウィジェットの使い方(p.059~p.060)# ② 「Menu」ウィジェットの使い方(p.060~p.061)# ③ データベースを作成する(p.061~p.062)# ④ 「蔵書管理アプリ」を完成させる(p.062~p.065)#========== リスト3ー2●「daily_memo.py」は、ここから# カレンダー型メモアプリのプログラム# このソースコードは、「memo.db」と同じフォルダに置くこと。# GUIライブラリーの「Tkinter」モジュールを、「tk」という名前でインポートする。import tkinter as tk# GUIライブラリーの「Tkinter.tkk」モジュールを、「tkk」という名前でインポートする。import tkinter.ttk as ttk# 「datetime」モジュールを、「da」という名前でインポートする。import datetime as da# 「calender」モジュールを、「ca」という名前でインポートする。import calendar as ca# 「Tkinter」モジュールから「messagebox」モジュールをインポートする。from tkinter import messagebox# データベースライブラリのインポート(「SQLite3」モジュール)import sqlite3# 日付を引数にしてメモを取得する関数def get_memo(day): # データベースの作成 # 「sqlite3.connect」関数でデータベースを作成する。 conn = sqlite3.connect('memo.db') # カーソルオブジェクトの作成 # カーソルオブジェクトでデータベースの操作を行う。 cur = conn.cursor() # 「today_memo」の初期化 today_memo = '' sql = 'SELECT * FROM daily WHERE date = ?' for row in cur.execute(sql, (day,)): today_memo = row[1] conn.close() return today_memo# 日付がクリックされた時に呼び出される関数def click(event): global click_day click_day = event.widget['text'] n = str(yer[0]) + '_' + str(mon[0]) + '_' + str(click_day) title['text'] = make_text_1(yer[0], mon[0], click_day) + 'のメモ' text.delete('1.0', 'end') text.insert('1.0', get_memo(n)) # 保存ボタンがクリックされた時に呼び出される関数def save(t_day): conn = sqlite3.connect('memo.db') cur = conn.cursor() sql = 'REPLACE INTO daily VALUES(?, ?)' cur.execute(sql, (t_day, text.get('1.0', 'end-1c'))) conn.commit() conn.close() messagebox.showinfo('メッセージ', 'データを保存しました。') disp(0) # 引数の日付にメモがあれば「True」、なければ「False」を返す関数def check(y, m, d): day = str(y) + '_' + str(m) + '_' + str(d) if (get_memo(day) != ''): return True return False# 日付文字列を作る関数def make_text_1(y, m, d): return str(y) + '年' + str(m) + '月' + str(d) + '日'def make_text_2(y, m, d): return str(y) + '_' + str(m) + '_' + str(d)# 表示するカレンダーの文字列WEEK = ['日', '月', '火', '水', '木', '金', '土']WEEK_COLOUR = ['red', 'black', 'black', 'black', 'black', 'black', 'blue'] def disp(arg): global yer global mon mon[0] += arg if mon[0] < 1: mon[0], yer[0] = 12, yer[0] - 1 elif mon[0] > 12: mon[0], yer[0] = 1, yer[0] + 1 label['text'] = str(yer[0]) + '年' + str(mon[0]) + '月' cal = ca.Calendar(firstweekday=6) for widget in frame.winfo_children(): widget.destroy() r = 0 for i, x in enumerate(WEEK): label_day = tk.Label(frame, text=x, font=('', 10), width=3, fg=WEEK_COLOUR[i]) label_day.grid(row=r, column=i, pady=1) r = 1 for week in cal.monthdayscalendar(yer[0], mon[0]): for i, day in enumerate(week): day = ' ' if day == 0 else day label_day = tk.Label(frame, text=day, font=('', 10), fg=WEEK_COLOUR[i], borderwidth=1) if (yer[0], mon[0], today) == (yer[1], mon[1], day): label_day['relief'] = 'solid' if check(yer[0], mon[0], day): label_day['background'] = 'yellow' label_day.bind('<Button-1>', click) label_day.grid(row=r, column=i, padx=2, pady=1) r = r + 1 # ウインドウを生成(リサイズ不可) # 「Tk」関数を使って、ウインドウ「(トップレベルtk」ウイジェット)を生成し、 「root」という名前を付ける。# 「Tk」関数は、「Tk」クラスから、ウインドウ(「トップレベルtk」ウイジェット)を生成するための関数。root = tk.Tk()# ウインドウの中身の大きさを指定# ウインドウの中身(タイトルバーなどを除いた内部)の大きさを「geometry」関数で指定する。# ('470x250')は、横サイズ=470ピクセル、縦サイズ=250ピクセルを表しているroot.geometry('470x250') # ウインドウの表示タイトルを「メモアプリ」にする。root.title('メモアプリ')# 「リサイズ不可」の設定root.resizable(0, 0)# カレンダー用のフレームc_frame = tk.Frame(root)frame = tk.Frame(c_frame)for n in range(3): c_frame.grid_columnconfigure(n, weight=1) yer = [da.date.today().year] * 2mon = [da.date.today().month] * 2today = da.date.today().dayclick_day = todaylabel = tk.Label(c_frame, font=('', 10))button_1 = tk.Button(c_frame, text='<', font=('', 10), command=lambda:disp(-1))button_1.grid(row=0, column=0, pady=10)label.grid(row=0, column=1)button_2 = tk.Button(c_frame, text='>', font=('', 10), command=lambda:disp(1))button_2.grid(row=0, column=2)frame.grid(row=1, column=0, columnspan=3)disp(0)# ここからメモ用のフレームd_frame = tk.Frame(root)# タイトルと保存ボタンt_frame = tk.Frame(d_frame)title = tk.Label(t_frame, text=make_text_1(yer[0], mon[0], today) + 'のメモ', font=('', 12))title.grid(row=0, column=0, padx=20)button = tk.Button(t_frame, text='保存', command=lambda:save(make_text_2(yer[0], \ mon[0], click_day)))button.grid(row=0, column=1)t_frame.grid(row=0, column=0, pady=10)# メモ用の「Textウイジェット」と「Scrollbar」ウイジェットtext = tk.Text(d_frame, width=30, height=14)text.grid(row=4, column=0)scroll_v = tk.Scrollbar(d_frame, orient=tk.VERTICAL, \ command=text.yview)scroll_v.grid(row=4, column=1, sticky=tk.N+tk.S)text["yscrollcommand"] = scroll_v.settext.insert('1.0', get_memo(make_text_2(yer[0],mon[0], today)))c_frame.grid(row=0, column=0, padx=10)d_frame.grid(row=0, column=1)# ウインドウを表示して、「メインループ」に入る。# 「mainloop(メインループ)」は、「イベントループ」で、ウインドウで発生する# 「イベント」を待っている状態のループ。root.mainloop()#========== リスト3ー2●「daily_memo.py」は、ここまでリスト3ー2●「daily_memo.py」の実行結果「保存」ボタンを押すことで、保存できました、