2017-10-24 29 views
-1

ボタンをクリックすると、ボタンの上に3つのエントリウィジェット(ユーザオプション)が配置された新しいフレームが作成される動的なGUIを作成しようとしています。 3つのエントリーウィジェット&からのユーザー入力を読み込むことが可能になるように変更することができます。ボタンを押すたびに、3つの新しい呼び出し可能な入力ウィジェットが表示されます。Tkinterはボタンからウィジェットを動的に作成します

エラーが発生していますが、リストに似た何かを使用してウィジェットを動的に作成できるので、間違っていることは知っていますか?

from Tkinter import * 

app = Tk() 

frameNames = [] 
widgetNames = [] 

def createwidgets(): 
    global widgetNames 
    global frameNames 
    frameNames += (str("g"+str(len(frameNames)))) #why does the letter & number get added as seperate elements? 
    widgetNames += [(str("w"+str(len(widgetNames)-1))), 
        (str("w"+str(len(widgetNames)))),  
        (str("w"+str(len(widgetNames)+1)))] 

    frameNames[len(frameNames) - 1] = Frame(app) 
    frameNames[len(frameNames) - 1].pack() 

    widgetNames[len(widgetNames) - 3] = Entry(frameNames[len(frameNames) - 1]) 
    widgetNames[len(widgetNames) - 3].pack() 
    widgetNames[len(widgetNames) - 2] = Entry(frameNames[len(frameNames -)- 1]) 
    widgetNames[len(widgetNames) - 2].pack() 
    widgetNames[len(widgetNames) - 1] = Entry(frameNames[len(frameNames) - 1]) 
    widgetNames[len(widgetNames) - 1].pack() 

createWidgetButton = Button(app, text="createWidgets", command=createwidgets()) 
createWidgetButton.grid(sticky=S) 

app.mainloop() 
+0

あなたが取得しているエラーは何か? –

+0

@ブライアン最後にコードを見たので問題は1つ修正しましたが、無限ループに入っていてアプリケーションが表示されていないようですウィジェット – WCTech

答えて

0

主な問題は、コードのこれらの4行です:

frameNames[len(frameNames) - 1] = Frame(app) 
frameNames[len(frameNames) - 1].pack() 
... 
createWidgetButton = Button(app, text="createWidgets", command=createwidgets()) 
createWidgetButton.grid(sticky=S) 

あなたはappの子としてフレームとボタンの両方を作成されていますが、一方及び他方のためのpackためgridを使用しています。あなたはappのすべての直系子孫と一貫していなければなりません。それらはすべてpackを使用するか、すべてgridを使用する必要があります。ここで

frameNames += (str("g"+str(len(frameNames)))) #why does the letter & number get added as seperate elements? 

frameNamesはリストであり、あなたは文字列でそれを追加しようとしている。

第二の問題は、この行です。追加は追加と同じではありません。追加する前に、新しい名前を追加するか、新しい名前を一時的なリストに入れる必要があります。

frameNames.append(str(...)) 

第三の問題は、この行される:

createWidgetButton = Button(app, text="createWidgets", command=createwidgets()) 

上記本と全く同じである。

result = createWidgets() 
createWidgetButton = Button(app, text="createWidgets", command=result) 

あなたは、関数へ参照しない通過しなければなりません関数を呼び出します。これまで行(createWidgets後の括弧の欠如に注意してください)に変更します。

問題とは無関係の
createWidgetButton = Button(app, text="createWidgets", command=createwidgets) 

をしていますが、一時的な変数を使用する代わりに繰り返した場合、あなたのコードが読みずっと容易になるだろうパターン(str("w"+str(len(widgetNames)-1)。書かれているように、あなたのコードはほとんど読むことが不可能です。また、ウィジェットの名前をに保存したくない場合は、実際のウィジェット自体を保存する必要があります。

最後に、ワイルドカードをインポートしないでください。それを行うには理由がありません。ここで

は、私はあなたのコードを書き換える方法は以下のようになります

import Tkinter as tk 

app = tk.Tk() 

frames = [] 
widgets = [] 

def createwidgets(): 
    global widgetNames 
    global frameNames 

    frame = tk.Frame(app, borderwidth=2, relief="groove") 
    frames.append(frame) 

    frame.pack(side="top", fill="x") 

    for i in range(3): 
     widget = tk.Entry(frame) 
     widgets.append(widget) 

     widget.pack(side="left") 

createWidgetButton = tk.Button(app, text="createWidgets", command=createwidgets) 
createWidgetButton.pack(side="bottom", fill="x") 

app.mainloop() 
0

これは比較的簡単です。

Frameウィジェットを作成して、それを詰め込むことなく、必要なものを記入してから、FrameウィジェットのパックをButtonに呼び出すことで、これを行うことができます。

多くの以下のような:あなたはこれらの形態の複数を追加する必要がある場合は、「自己を持っているために、匿名関数(lambda)を利用し、それ以下のように

from tkinter import * 

class App: 
    def __init__(self, root): 
     self.root = root 
     self.create = Button(self.root, text="Create", command=self.draw) 
     self.create.pack(side="bottom") 
     self.frame = Frame(self.root) 
     self.entry1 = Entry(self.frame) 
     self.entry2 = Entry(self.frame) 
     self.entry3 = Entry(self.frame) 
     self.entry1.pack() 
     self.entry2.pack() 
     self.entry3.pack() 
     self.submit = Button(self.frame, text="Submit", command=self.command) 
     self.submit.pack() 
    def draw(self): 
     self.frame.pack(side="top") 
    def command(self): 
     print(self.entry1.get()) 
     print(self.entry2.get()) 
     print(self.entry3.get()) 

root = Tk() 
App(root) 
root.mainloop() 

あなたが何かを行うことができます彼らはにいるどのフレーム 『知っている意識」ボタン』:

from tkinter import * 

class App: 
    def __init__(self, root): 
     self.frames = [] 
     self.entries = [] 
     self.count = 0 
     self.root = root 
     self.create = Button(self.root, text="Create", command=self.draw) 
     self.create.pack(side="bottom") 
    def draw(self): 
     self.frames.append(Frame(self.root, borderwidth=1, relief="solid")) 
     self.frames[self.count].pack(side="top") 
     self.entries.append([Entry(self.frames[self.count]), Entry(self.frames[self.count]), Entry(self.frames[self.count])]) 
     for i in self.entries[self.count]: 
      i.pack() 
     Button(self.frames[self.count], text="Submit", command=lambda c=self.count: self.submit(c)).pack() 
     self.count += 1 
    def submit(self, c): 
     for i in self.entries[c]: 
      print(i.get()) 

root = Tk() 
App(root) 
root.mainloop() 
+0

新しいウィジェットごとにデータを取得する方法で、そのボタンを何度もクリックする必要があります。 – WCTech

+0

あなたの最初の質問にはなかった。私は解決策を提供しました。 –

+0

最初の質問でボタンを再利用する必要があることが完全にはっきりしていないかもしれないことを私は理解しています。 – WCTech

関連する問題