カスタム フィールドを持つさまざまなダイアログ ウィンドウの親クラスとして使用される独自のバージョンの Dialog クラスを作成しました。下部にあるのは、Dialog クラスのコードです。ダイアログ タイプのウィンドウの 1 つに、ユーザーが独自の値を入力できるコンボボックス (ドロップダウン ボックス) があります。ユーザーが独自の値 (名前) を入力し、それが (ファイルからの) 顧客のリストに含まれていない場合、新しい顧客を追加するかどうかをユーザーに尋ねます。[はい] を選択すると、入力した名前を親ウィンドウ (アプリケーションのルート) に渡し、名前を入力したダイアログ ボックスを閉じ、別のダイアログを開いて新しい顧客の情報を入力します (以前に入力した名前)。値を渡すことを除いて、これのすべての部分が機能します。
この値をどのように渡す必要がありますか? 私の最初の考えは、カスタムの Tkinter イベントを使用することでした。ただし、その方法に関する情報は見つかりません。
最初の子ダイアログを作成するルート メソッド:
def check_in(self):
log_diag = LoggerDialog(self,self.customers)
try:
log_diag.show()
except NewCustomerException, (instance):
self.new_customer(str(instance))
except:
print instance
子ダイアログ ボックス内:
def new_customer_error(self):
#parse name and preset values in the new customer dialog
name = self.name.get()
if askquestion(title="New Customer?",
message="Add new customer: " + name,
parent = self.root) == 'yes':
raise NewCustomerException(name)
ダイアログクラス:
class Dialog:
def __init__(self, master, title, class_=None, relx=0.5, rely=0.3):
self.master = master
self.title = title
self.class_ = class_
self.relx = relx
self.rely = rely
def setup(self):
if self.class_:
self.root = Toplevel(self.master, class_=self.class_)
else:
self.root = Toplevel(self.master)
self.root.title(self.title)
self.root.iconname(self.title)
def enable(self):
### enable
self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window)
self._set_transient(self.relx, self.rely)
self.root.wait_visibility()
self.root.grab_set()
self.root.mainloop()
self.root.destroy()
def _set_transient(self, relx=0.5, rely=0.3):
widget = self.root
widget.withdraw() # Remain invisible while we figure out the geometry
widget.transient(self.master)
widget.update_idletasks() # Actualize geometry information
if self.master.winfo_ismapped():
m_width = self.master.winfo_width()
m_height = self.master.winfo_height()
m_x = self.master.winfo_rootx()
m_y = self.master.winfo_rooty()
else:
m_width = self.master.winfo_screenwidth()
m_height = self.master.winfo_screenheight()
m_x = m_y = 0
w_width = widget.winfo_reqwidth()
w_height = widget.winfo_reqheight()
x = m_x + (m_width - w_width) * relx
y = m_y + (m_height - w_height) * rely
if x+w_width > self.master.winfo_screenwidth():
x = self.master.winfo_screenwidth() - w_width
elif x < 0:
x = 0
if y+w_height > self.master.winfo_screenheight():
y = self.master.winfo_screenheight() - w_height
elif y < 0:
y = 0
widget.geometry("+%d+%d" % (x, y))
widget.deiconify() # Become visible at the desired location
def wm_delete_window(self):
self.root.quit()
generate_event() を使用してカスタム パラメーター (名前) を渡そうとしたところ、次のエラーが発生しました。
TclError: bad option "-name": must be -when, -above, -borderwidth,
-button, -count, -data, -delta, -detail, -focus, -height, -keycode,
-keysym, -mode, -override, -place, -root, -rootx, -rooty, -sendevent,
-serial, -state, -subwindow, -time, -warp, -width, -window, -x, or -y
これらのいくつかの値をオーバーライドしようとしましたが、間違った型を渡したというエラーが返され続けています。(mode は int で、detail はオブジェクトの特定のリストのインスタンスでなければなりません) これはあまり洗練された解決策ではないようです。
これが私が落ち着いた解決策です:
子オブジェクトのコード (データベースにない名前を処理するため):
def new_customer_error(self):
if askquestion(title="New Customer?",
message="Add new customer: " + self.name.get(),
parent = self.root) == 'yes':
self.master.event_generate('<<NewCustomer>>')
ルート__init__
ウィンドウ内:
self.bind('<<NewCustomer>>',self.new_customer)
後でルートオブジェクトで:
def new_customer(self, event=None):
#if evert this came as a new customer entry through check in
if event:
temp = self.logger_diag.name.get().split(' ')
self.newc_diag.fname.set(temp[0])
if len(temp) == 2:
self.newc_diag.lname.set(temp[1])
elif len(temp) == 3:
self.newc_diag.mname.set(temp[1])
self.newc_diag.lname.set(temp[2])
elif len(temp) > 3:
self.newc_diag.mname.set(temp[1])
self.newc_diag.lname.set(' '.join(temp[2:4]))