۷. بهروزرسانی جدول و انتخاب ردیف¶
خط ۱۱۳ تا ۱۲۷
دو تابع این بخش جدول را با فرم هماهنگ نگه میدارند. refresh جدول را خالی و از نو پر میکند، و choose وقتی روی یک ردیف کلیک شود اطلاعات آن را در جعبههای فرم مینویسد.
کد این بخش¶
113def refresh(query=''):114 for item in table.get_children():115 table.delete(item)116 for name, p in shop.products.items():117 if query in name.lower():118 table.insert('', 'end', values=(name, p['buy'], p['sell'], p['qty']))119 120def choose(event):121 selection = table.selection()122 if not selection:123 return124 name, buy, sell_price, qty = table.item(selection[0], 'values')125 for key, value in [('name', name), ('buy', buy), ('sell', sell_price), ('qty', qty)]:126 fields[key].delete(0, tk.END)127 fields[key].insert(0, value)
روی شمارهی هر خط بزن تا به توضیحش بروی؛ روی «خط …» در توضیح بزن تا همان خط در کد روشن شود.
توضیح خط به خط¶
- خط ۱۱۳
def refresh(query=''):¶ - تابع
refreshبا یک پارامتر اختیاری. اگر چیزی داده نشودqueryرشتهی خالی است و همهی کالاها نمایش داده میشوند. این تابع ازtableاستفاده میکند که تازه در خط ۱۳۷ ساخته میشود؛ مشکلی پیش نمیآید چون بدنهی تابع تا وقتی صدا زده نشود اجرا نمیشود و اولین صدا زدن در خط ۱۴۵ است. - خط ۱۱۵
table.delete(item)¶ - هر ردیف را از جدول پاک میکند. این فقط ردیف نمایشی است و کالا از فروشگاه حذف نمیشود (برخلاف
Shop.deleteدر خط ۴۴). - خط ۱۱۶
for name, p in shop.products.items():¶ - روی همهی کالاها حلقه میزند.
items()جفتهای (کلید، مقدار) را میدهد:nameنام کالا وpدیکشنری قیمتها و موجودی. - خط ۱۱۷
if query in name.lower():¶ - فقط کالاهایی را نشان میدهد که متن جستوجو در نامشان باشد. رشتهی خالی در هر رشتهای «وجود دارد»، پس
'' in nameهمیشهTrueاست و همه نمایش داده میشوند. - خط ۱۱۸
table.insert('', 'end', values=(name, p['buy'], p['sell'], p['qty']))¶ - یک ردیف به جدول اضافه میکند.
''یعنی ردیف در سطح اصلی است (زیرمجموعهی ردیف دیگری نیست)،'end'یعنی ته جدول، وvaluesمقدار چهار ستون به ترتیب خط ۱۳۶ است. - خط ۱۲۰
def choose(event):¶ - تابع
chooseبرای رویداد انتخاب ردیف. tkinter هنگام صدا زدن یک شیء رویداد به آن میدهد، پس پارامترeventلازم است حتی اگر استفاده نشود. در خط ۱۴۲ به جدول وصل میشود. - خط ۱۲۲
if not selection:¶ - اگر چیزی انتخاب نشده باشد... این حالت مثلاً وقتی پیش میآید که
refreshردیف انتخابشده را پاک کند و رویداد با انتخاب خالی اجرا شود. - خط ۱۲۴
name, buy, sell_price, qty = table.item(selection[0], 'values')¶ - مقدارهای اولین ردیف انتخابشده را میگیرد و در چهار متغیر باز میکند. نام
sell_price(بهجایsell) انتخاب شده تا با تابعsell(خط ۱۰۲) اشتباه نشود. این مقدارها از جدول بهشکل رشته برمیگردند، مثلاً'242400.0'.
یادداشت
بعد از کلیک روی یک ردیف، جعبهی «تعداد» موجودی کالا را نشان میدهد. برای ثبت فروش باید آن را به تعداد فروش تغییر دهی، وگرنه کل موجودی فروخته میشود.
ارتباط با بقیهی کد¶
همچنین ببینید
refresh(query='')- صدا زدهشدن در
runخط ۸۷،searchخط ۱۰۷، دکمهی «نمایش همه» خط ۱۳۰ و پر کردن اولیهی جدول خط ۱۴۵. choose(event)- در خط ۱۴۲ به رویداد
<<TreeviewSelect>>جدول وصل میشود. table- در خط ۱۳۷ ساخته میشود.
fields- در خط ۷۰ ساخته و در خط ۷۵ پر میشود.
shop.products- دادهای که در خط ۳۳، خط ۴۱، خط ۴۷ و خط ۵۸ تغییر میکند.
سؤالهای تمرینی¶
اول خودت جواب بده، بعد جواب را باز کن.
چرا
refresh()بدون ورودی همهی کالاها را نشان میدهد؟نمایش جواب
queryبرابر''است و رشتهی خالی در هر رشتهای هست، پس شرط خط ۱۱۷ همیشه درست است.آیا
table.delete(item)در خط ۱۱۵ کالا را از فروشگاه حذف میکند؟نمایش جواب
نه. فقط ردیف جدول را پاک میکند و دادهی
shop.productsدست نمیخورد.chooseازeventاستفاده نمیکند. پس چرا این پارامتر هست؟نمایش جواب
tkinter همیشه یک شیء رویداد به تابع وصلشده (خط ۱۴۲) میدهد؛ بدون این پارامتر صدا زدن تابع خطای
TypeErrorمیداد.مقدارهایی که
table.item(...)در خط ۱۲۴ برمیگرداند چه نوعی دارند؟نمایش جواب
رشته، مثلاً
'242400.0'.