実現したいこと
TkinterのGUIを作成しています。TreeViewを使用し、表のウィンドウをGUIに表示しています。そのウィンドウに横スクロール、縦スクロールできるようにスクロールバーをつけたいです。
発生している問題・分からないこと
スクロールバーらしきものは表示されるのですが、機能しません。どうか教えていただけますと幸いです。
該当のソースコード
Python
1import tkinter as tk 2from tkinter import ttk, filedialog, messagebox 3import pandas as pd 4import os 5import subprocess 6 7class SearchApp: 8 def __init__(self, root): 9 self.root = root 10 self.root.title("顧客検索システム") 11 12 # デフォルトのCSVデータファイル(仮) 13 self.default_db_path = r"C:\\Users\\proba\\Desktop\\animal_hospital_index\\animal_customer_db.csv" 14 15 # CSVデータを格納するDataFrame 16 self.df = None # 仮に空のデータフレームで初期化(後で実際のデータを読み込む) 17 self.load_default_database() # データベースをロード 18 19 # メインフレーム 20 self.main_frame = ttk.Frame(root) 21 self.main_frame.grid(row=0, column=0, padx=10, pady=10) 22 23 # 検索条件の入力フィールド 24 self.name_label = ttk.Label(self.main_frame, text="顧客名(カタカナ)") 25 self.name_label.grid(row=0, column=0, padx=5, pady=5, sticky="e") 26 self.name_entry = ttk.Entry(self.main_frame) 27 self.name_entry.grid(row=0, column=1, padx=5, pady=5) 28 29 self.pet_name_label = ttk.Label(self.main_frame, text="ペット名(カタカナ)") 30 self.pet_name_label.grid(row=1, column=0, padx=5, pady=5, sticky="e") 31 self.pet_name_entry = ttk.Entry(self.main_frame) 32 self.pet_name_entry.grid(row=1, column=1, padx=5, pady=5) 33 34 self.phone_label = ttk.Label(self.main_frame, text="電話番号の下四桁") 35 self.phone_label.grid(row=2, column=0, padx=5, pady=5, sticky="e") 36 self.phone_entry = ttk.Entry(self.main_frame) 37 self.phone_entry.grid(row=2, column=1, padx=5, pady=5) 38 39 # 検索ボタン 40 self.search_button = ttk.Button(self.main_frame, text="検索", command=self.search) 41 self.search_button.grid(row=3, column=0, columnspan=2, pady=10) 42 43 # Treeviewフレーム 44 self.tree_frame = ttk.Frame(root, width=800, height=300) # フレームのサイズを調整 45 self.tree_frame.grid(row=1, column=0, padx=10, pady=10, sticky="nsew") 46 47 # 横スクロールバー 48 self.tree_scroll_x = ttk.Scrollbar(self.tree_frame, orient="horizontal") 49 self.tree_scroll_x.pack(side="bottom", fill="x") 50 51 # 縦スクロールバー 52 self.tree_scroll_y = ttk.Scrollbar(self.tree_frame, orient="vertical") 53 self.tree_scroll_y.pack(side="right", fill="y") 54 55 # Treeviewウィジェットの作成(固定高さ・幅) 56 self.tree = ttk.Treeview(self.tree_frame, columns=("customer_id", "name_kanji", "name_katakana", "pet_kind", "pet_name", "pet_name_katakana", "pet_birth", "pet_sex", "telephone_number", "cellphone_number", "adress"), 57 show='headings', xscrollcommand=self.tree_scroll_x.set, yscrollcommand=self.tree_scroll_y.set, 58 height=15) # 高さを15行に設定(適宜調整) 59 60 self.tree.pack(side="left", fill="both", expand=True) 61 62 # スクロールバーとTreeviewの連携 63 self.tree_scroll_x.config(command=self.tree.xview) 64 self.tree_scroll_y.config(command=self.tree.yview) 65 66 # カラムの設定 67 columns = ["customer_id", "name_kanji", "name_katakana", "pet_kind", "pet_name", "pet_name_katakana", "pet_birth", "pet_sex", "telephone_number", "cellphone_number", "adress"] 68 for col in columns: 69 self.tree.heading(col, text=col) 70 self.tree.column(col, width=100, anchor="center") # 列の幅を設定 71 72 # ソースボタン 73 self.source_button = ttk.Button(root, text="ソース", command=self.open_source) 74 self.source_button.grid(row=2, column=0, pady=10) 75 76 def load_default_database(self): 77 """デフォルトのデータベースを読み込む""" 78 try: 79 self.df = pd.read_csv(self.default_db_path, encoding='utf-8') 80 except Exception as e: 81 print(f"デフォルトのデータベースを読み込む際にエラーが発生しました:\n{e}") 82 83 def open_source(self): 84 """CSVファイルを開く""" 85 try: 86 if os.path.exists(self.default_db_path): 87 subprocess.Popen(["notepad", self.default_db_path]) 88 else: 89 messagebox.showerror("エラー", "データベースファイルが存在しません。") 90 except Exception as e: 91 messagebox.showerror("エラー", f"CSVファイルを開く際にエラーが発生しました:\n{e}") 92 93 def search(self): 94 """検索機能の実装""" 95 if self.df is None: 96 print("データベースが読み込まれていません。") 97 return 98 99 name_katakana = self.name_entry.get() 100 pet_name_katakana = self.pet_name_entry.get() 101 phone_last4 = self.phone_entry.get() 102 103 # 条件を動的に構築 104 conditions = [] 105 if name_katakana: 106 conditions.append(self.df['name_katakana'].str.contains(name_katakana, na=False)) 107 if pet_name_katakana: 108 conditions.append(self.df['pet_name_katakana'].str.contains(pet_name_katakana, na=False)) 109 if phone_last4: 110 conditions.append((self.df['telephone_number'].astype(str).str[-4:].str.contains(phone_last4, na=False)) | 111 (self.df['cellphone_number'].astype(str).str[-4:].str.contains(phone_last4, na=False))) 112 113 # 条件が1つ以上ある場合にフィルタリング 114 if conditions: 115 result_df = self.df[conditions[0]] 116 for condition in conditions[1:]: 117 result_df = result_df[condition] 118 else: 119 result_df = self.df # 条件がない場合は全データ 120 121 # Treeviewウィジェットのクリア 122 for i in self.tree.get_children(): 123 self.tree.delete(i) 124 125 # 結果をTreeviewに表示 126 for _, row in result_df.iterrows(): 127 self.tree.insert("", "end", values=list(row)) 128 129# アプリケーションの実行 130if __name__ == "__main__": 131 root = tk.Tk() 132 app = SearchApp(root) 133 root.mainloop() 134
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
横スクロールを試している方の投稿を見たのですが、解決できませんでした。
補足
特になし

回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2025/01/22 02:18
2025/01/22 09:40