0

背景について: 私の経験のほとんどは ruby​​/rails です。Excel ファイルを更新する単純な GUI アプリを構築することで友人を助けようとしていますが、Python や TKinter の経験はあまりありません。目標は、単純なフォームを作成することです。ユーザーが数字を入力すると、別のフォームがドロップダウン メニューとともに表示されます。2 つのフレーム間で変数を渡すのに問題があったため、指定された数値をグローバル変数に格納することにしました。グローバル変数の設定と 2 番目のフレームへの切り替えの両方を管理できません。私が持っていたその他の質問/問題は、## マークの付いたコメントにあります。

あるいは、MDB や Excel ファイルにアクセスできるクロス プラットフォーム アプリを作成するための最善の方法について何かアイデアがあれば、私はすべて耳にします。これがどれほど困難であったかは、私を吹き飛ばします。助けてくれてありがとう。

import Tkinter as tk

TITLE_FONT = ("Helvetica", 18, "bold")
ID_NUMBER = None

class StatusApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (EntryPage, StatusPage):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(EntryPage)

    def show_frame(self, c):
        '''Show a frame for the given class'''
        frame = self.frames[c]
        frame.tkraise()

class EntryPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent) 
        label = tk.Label(self, text="Enter ID:", font=TITLE_FONT)
        self.entry = tk.Entry(self)
        ## Using the lambda works to switch frames, but I need to be able to execute 
        ## multiple statements.
        # entry.bind('<Return>', lambda event: controller.show_frame(StatusPage))

        ## In examples I've seen, callback has been used without the empty parens, not sure
        ## why they're needed?
        self.entry.bind('<Return>', self.callback())
        label.pack(side="top", fill="x", pady=10)
        self.entry.pack()
        self.entry.focus_set()

    def callback(self):
        ## I noticed the following gets fired once the program starts
        print 'hello'

        ## For some reason it says that entry doesn't have the attribute 'set'. I don't
        ## understand this as I'm calling it like a method.
        self.entry.set('hello')

        ## Ultimately setting the global ID_NUMBER variable is one of the main goals of this
        ## function
        ID_NUMBER = self.entry.get()

        ## I haven't been able to switch frames from within this function, only w/ a lambda as
        ## seen on line 34.
        # show_frame(StatusPage())

class StatusPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent) 
        label = tk.Label(self, text="ID: ", font=TITLE_FONT)
        optionList = ('train', 'plane', 'boat')
        selected_opt = tk.StringVar()
        selected_opt.set(ID_NUMBER)
        menu = tk.OptionMenu(self, selected_opt, *optionList)
        button = tk.Button(self, text="Save", command=lambda: controller.show_frame(EntryPage))
        label.pack(side="top", fill="x", pady=10)
        menu.pack()
        button.pack()

if __name__ == "__main__":
    app = StatusApp()
    app.mainloop()
4

1 に答える 1

0

バインディングのオブジェクトは、呼び出し可能な関数への参照である必要があります。Lambdaは、無名関数を作成して参照を返すため、このコンテキストでよく使用されます)。

を実行...bind(..., self.callback())すると、bindステートメントの実行時にその関数が呼び出されます。コードでコメントを作成し## I noticed the following gets fired once the program startsます; これが理由です。この関数呼び出しの結果は、バインディングに関連付けられているものです。かなり頻繁に、そしてあなたの特定のケースでは、これは値Noneです。省略しなければなりません()

あなたが書いたコードコメントで

## For some reason it says that entry doesn't have the attribute 'set'. I don't
## understand this as I'm calling it like a method.
self.entry.set('hello')

エントリウィジェットにsetメソッドがあると思われる理由は何ですか?私が知っているドキュメントはその主張をしていません。エラーメッセージは正しいです。エントリウィジェットには「set」という名前の属性がありません(関数はこのコンテキストでは属性と見なされます)。

于 2013-02-28T13:47:12.323 に答える