- 締切済み
pythonのGUIでmysqlにデータを追加する
pythonを使いmysqlにデータをインサートする方法としてTkEasyGUIを使って実行したいと思ってい、そこでpysimpleguiを使った「Pythonを使ってDBのテーブルをGUIで簡単に操作-https://qiita.com/kouki67/items/a63b92da32bc735a0316」を参考にカテゴリテーブルだけインサートすることを目指し下記コードのように作ってみることが出来ましたが、一応削除や追加は出来ますが残念なことにプログラム等に関してコピペを主に使う自己流の素人なものでこのコード正しいものかどうか分かりません。故にこのコードに余分な部分やおかしな点があればお教えください。 import TkEasyGUI as eg import mysql.connector HOSTIP = "127.0.0.1" USER = "root" PASS = "********1234" DATABASE = "category" #カテゴリ保存用リスト category_list = [] #データを取得 def selectItem(): category_list.clear() cur.execute("SELECT * FROM categoryMstr") for i in cur.fetchall(): category_list.append(list(i)) return cur.fetchall() #categoryMstrにデータを挿入 def insertItem(categoryName): try: with con.cursor() as cur: sql = "INSERT INTO categoryMstr (categoryName) values(%s);" cur.execute(sql, (categoryName,)) con.commit() except: con.rollback() con.commit() #categoryMstrからデータ削除 def deleteItem(deleteID): try: with con.cursor() as cur: sql = "DELETE FROM categoryMstr WHERE categoryID=%s" cur.execute(sql,(deleteID,)) con.commit() except: con.rollback() #削除した時にauto_incrementを初期化する try: with con.cursor() as cur: sql = "ALTER TABLE categoryMstr auto_increment = 1;" cur.execute(sql) con.commit() except: con.rollback() con.commit() #データベースに接続 con = mysql.connector.connect(host=HOSTIP, user=USER, password=PASS,database=DATABASE) #カーソルを準備 cur = con.cursor() #表に値を入れるために名前を取得 selectItem() # layput部 layout = [[ eg.Table( category_list, headings=["ID","カテゴリ"], auto_size_columns=False, key="-tbl_01-", col_widths=[3, 10], justification='left' )], [eg.Submit("削除",key="-btn_del-")], [eg.Text("追加するカテゴリ名"),eg.Input(key = "-input_name-")], [eg.Submit("追加",key="-btn_add-",color=("red"))]] # window部 window = eg.Window("カテゴリ管理", layout) # event部 while True: event, values = window.read() #追加ボタンが押されたら if event == "-btn_add-": #追加カテゴリ名を取得 categoryName = values["-input_name-"] #入力欄をからにする window["-input_name-"].update("") #未入力の場合 if categoryName == "": eg.popup("未入力です。",title="エラー") print("add") else: insertItem(categoryName) selectItem() #テーブルを更新 window["-tbl_01-"].update(values = category_list) #削除ボタンが押されたら if event == "-btn_del-": if values["-tbl_01-"] != []: #選択されているIDを取得 categoryID = category_list[values["-tbl_01-"][0]][0] deleteItem(categoryID) selectItem() #テーブルを更新 window["-tbl_01-"].update(values = category_list) #×ボタンが押されたら if event == eg.WIN_CLOSED: cur.close() con.close() break
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- AIエージェント あい(@OKWAVE-AI)
- ベストアンサー率89% (2715/3019)
あなたが作成したコードの基本的な流れは正しいですが、いくつか改善点と修正点がありますので、ご紹介いたします。 1. **ライブラリのインポート部分**: `TkEasyGUI`は記載されていますが、`import PySimpleGUI as sg`が正しいと思われます。基本的なGUIライブラリとして`PySimpleGUI`を使用します。 2. **データベース接続の初期化位置**: データベース接続とカーソルの初期化を関数内で行うことで、スコープ(範囲)の問題を防げます。また、接続オブジェクトのクローズは適切に行われているか確認してください。 3. **エラー処理**: `except`句では具体的な例外を捕捉した方が良いです。また、`con.commit()`の重複がありますので削除してください。 以下は改善後のコードです: ```python import PySimpleGUI as sg import mysql.connector HOSTIP = "127.0.0.1" USER = "root" PASS = "********1234" DATABASE = "category" # カテゴリ保存用リスト category_list = [] def create_connection(): return mysql.connector.connect(host=HOSTIP, user=USER, password=PASS, database=DATABASE) # データを取得 def selectItem(): category_list.clear() conn = create_connection() cur = conn.cursor() cur.execute("SELECT * FROM categoryMstr") for i in cur.fetchall(): category_list.append(list(i)) cur.close() conn.close() # categoryMstrにデータを挿入 def insertItem(categoryName): conn = create_connection() try: with conn.cursor() as cur: sql = "INSERT INTO categoryMstr (categoryName) values(%s);" cur.execute(sql, (categoryName,)) conn.commit() except mysql.connector.Error as e: print(f"Error: {e}") conn.rollback() finally: conn.close() # categoryMstrからデータ削除 def deleteItem(deleteID): conn = create_connection() try: with conn.cursor() as cur: sql = "DELETE FROM categoryMstr WHERE categoryID=%s" cur.execute(sql, (deleteID,)) conn.commit() except mysql.connector.Error as e: print(f"Error: {e}") conn.rollback() finally: conn.close() try: with conn.cursor() as cur: sql = "ALTER TABLE categoryMstr auto_increment = 1;" cur.execute(sql) conn.commit() except mysql.connector.Error as e: print(f"Error: {e}") conn.rollback() finally: conn.close() # 初期データ取得 selectItem() # レイアウト部 layout = [[ sg.Table( category_list, headings=["ID", "カテゴリ"], auto_size_columns=False, key="-tbl_01-", col_widths=[3, 10], justification='left' )], [sg.Submit("削除", key="-btn_del-")], [sg.Text("追加するカテゴリ名"), sg.Input(key="-input_name-")], [sg.Submit("追加", key="-btn_add-", button_color=("red"))]] # ウィンドウ部 window = sg.Window("カテゴリ管理", layout) # イベント部 while True: event, values = window.read() if event == sg.WIN_CLOSED: break if event == "-btn_add-": categoryName = values["-input_name-"] window["-input_name-"].update("") if categoryName == "": sg.popup("未入力です。", title="エラー") print("add") else: insertItem(categoryName) selectItem() window["-tbl_01-"].update(values=category_list) if event == "-btn_del-": if values["-tbl_01-"]: categoryID = category_list[values["-tbl_01-"][0]][0] deleteItem(categoryID) selectItem() window["-tbl_01-"].update(values=category_list) window.close() ``` このコードで、基本的な機能が動作するはずです。引き続き開発を頑張ってください。 ------------------------------------------------ こちらの回答はAIエージェント「あい」による参考回答です。 有識者からの回答も是非お待ちしています。 OKWAVEのAIに対する取り組みについてはこちらをご確認ください。 https://staffblog.okwave.jp/2023/06/07/10415/
お礼
AIエージェント あいの回答について 回答コードの善し悪しは別にして、質問は、TkEasyGUIを使うことを前提にしておりそこで記述したコードはpysimpleguiで作られたコードを参考のしていることを明記しているににもかかわらず、 「1. **ライブラリのインポート部分**: `TkEasyGUI`は記載されていますが、`import PySimpleGUI as sg`が正しいと思われます。基本的なGUIライブラリとして`PySimpleGUI`を使用します。」 という回答がなされている・・・相変わらず不思議なレトリックでの回答で・・・質問した私で回答コードの評価をどう下していいか分からないのが現状です
補足
残念なことに、PySimpleGUI の改善後のコードは一部機能しません。 参考サイトでFはtable等Frameで囲んでいたレイアウトになっていたのでTkEasyGUIの方も同じようなレイアウトにしてみましたがずーと解らないのがwindowの背景色とtableのbackground_colorの設定方法です。出来るかどうかもよく分からないのが現状です。 #Frameを付けたコード・・参考まで import TkEasyGUI as eg import mysql.connector HOSTIP = "127.0.0.1" USER = "root" PASS = "mysql1972qb" DATABASE = "category" #カテゴリ保存用リスト category_list = [] #データを取得 def selectItem(): category_list.clear() cur.execute("SELECT * FROM categoryMstr") for i in cur.fetchall(): category_list.append(list(i)) return cur.fetchall() #categoryMstrにデータを挿入 def insertItem(categoryName): try: with con.cursor() as cur: sql = "INSERT INTO categoryMstr (categoryName) values(%s);" cur.execute(sql, (categoryName,)) con.commit() except: con.rollback() con.commit() #categoryMstrからデータ削除 def deleteItem(deleteID): try: with con.cursor() as cur: sql = "DELETE FROM categoryMstr WHERE categoryID=%s" cur.execute(sql,(deleteID,)) con.commit() except: con.rollback() #削除した時にauto_incrementを初期化する try: with con.cursor() as cur: sql = "ALTER TABLE categoryMstr auto_increment = 1;" cur.execute(sql) con.commit() except: con.rollback() con.commit() #データベースに接続 con = mysql.connector.connect(host=HOSTIP, user=USER, password=PASS,database=DATABASE) #カーソルを準備 cur = con.cursor() #表に値を入れるために名前を取得 selectItem() # layput部 eg.theme('clam') layout = [ [eg.Frame( "カテゴリ一覧'", [ [eg.Table( category_list, headings=["ID","カテゴリ"], auto_size_columns=False, key="-tbl_01-", col_widths=[3, 10], justification='left', pad=(15,5) )], [eg.Button("削除",key="-btn_del-",background_color=("#FF8000"),pad=((150,1),(1,5)))], ], background_color='pink', color='red', font=("Arial", 9), ) ], [eg.Frame( "追加するカテゴリ名'", [ [eg.Input(key = "-input_name-",pad=(25,5) )], [eg.Submit("追加",key="-btn_add-",background_color=("#FFFFAA"))]], background_color='red', color='white', font=("Arial", 9), )] ] # window部 window = eg.Window("カテゴリ管理", layout,size=(250, 420)) # event部 while True: event, values = window.read() #追加ボタンが押されたら if event == "-btn_add-": #追加カテゴリ名を取得 categoryName = values["-input_name-"] #入力欄をからにする window["-input_name-"].update("") #未入力の場合 if categoryName == "": eg.popup("未入力です。",title="エラー") print("add") else: insertItem(categoryName) selectItem() #テーブルを更新 window["-tbl_01-"].update(values = category_list) #削除ボタンが押されたら if event == "-btn_del-": if values["-tbl_01-"] != []: #選択されているIDを取得 categoryID = category_list[values["-tbl_01-"][0]][0] deleteItem(categoryID) selectItem() #テーブルを更新 window["-tbl_01-"].update(values = category_list) #×ボタンが押されたら if event == eg.WIN_CLOSED: cur.close() con.close() break window.close()