2017-11-28 4 views
0

私は初めてtkinterを始めたばかりで、いくつかの問題にぶち当たっています。私はいくつかのリストをユーザに表示し、各リストの選択肢を辞書に保存したい(後でデータフレームのいくつかのカラムをフィルタリングするために使用する)。例えば、1)「Brand」とラベル付けされ、「Brand X」と「Brand Y」をオプションとして含む1つの2つのリスト、「New」、「Existing」、「All」を含む別の「Customer Type」の2つのリスト"tkinterでバインドするときに別の引数を渡すにはどうしたらいいですか?

「Brand X」、「New」、「All」のいずれかを選択すると、「Brand」:['Brand X ']、[顧客タイプ]:[' New '、' All ']} 1つのリストを取得するのは簡単ですが、リストをループすると問題が発生します。

私がこれまでに以下のコードを持っている:回答

from tkinter import * 
from tkinter import ttk 


class checkList(Frame): 
    def __init__(self, options, parent=None): 
     Frame.__init__(self, parent) 
     self.makeHeader() 
     self.options = options 
     self.pack(expand=YES, fill=BOTH, side=LEFT) 
     self.makeWidgets(self.options) 
     self.selections = [] 

    def makeHeader(self): 
     header = ttk.Label(self,text='Please select options to limit on.') 
     header.pack(side=TOP) 
     self.header = header 

    def makeWidgets(self, options): 
     for key in self.options.keys(): 
      lbl = ttk.Label(self, text=key) 
      lbl.pack(after=self.header) 
      listbox = Listbox(self, selectmode=MULTIPLE, exportselection=0) 
      listbox.pack(side=LEFT) 
      for item in self.options[key]: 
       listbox.insert(END, item) 
      listbox.bind('<<ListboxSelect>>', self.onselect) 
      self.listbox = listbox 

    def onselect(self, event): 
     selections = self.listbox.curselection() 
     selections = [int(x) for x in selections] 
     self.selections = [self.options[x] for x in selections] 


if __name__ == '__main__': 
    options = {'Brand':['Brand','Brand Y'], 'Customer Type': ['All Buyers','New Buyers','Existing Buyers']} 
    checkList(options).mainloop() 

言うまでもなくを、[self.options [x]は、選択中のxについて]が一つだけのリストとの素晴らしい作品が、私は辞書を持っているので、私は本当に[self.options [key] [x]は選択肢の中でxが必要です。]しかし、私はどのようにループの任意のポイントでキーを渡すかを理解することはできません。私がやろうとしていることを達成する方法はありますか?

答えて

1

tkinterオブジェクトが拡張可能であるため、キーを渡すために探している "マジック"は単純です。あなたのコードはうまくいくと思います。

from tkinter import * 
from tkinter import ttk 


class checkList(Frame): 
    def __init__(self, options, parent=None): 
     Frame.__init__(self, parent) 
     self.makeHeader() 
     self.options = options 
     self.pack(expand=YES, fill=BOTH, side=LEFT) 
     self.listboxes = [] # New 
     self.makeWidgets(self.options) 
     self.selections = {} # Changed 

    def makeHeader(self): 
     header = ttk.Label(self,text='Please select options to limit on.') 
     header.pack(side=TOP) 
     self.header = header 

    def makeWidgets(self, options): 
     for key in self.options.keys(): 
      lbl = ttk.Label(self, text=key) 
      lbl.pack(after=self.header) 
      listbox = Listbox(self, selectmode=MULTIPLE, exportselection=0) 
      listbox.key = key # here's the magic you were asking about... 
      listbox.pack(side=LEFT) 
      self.listboxes.append(listbox) # New 
      for item in self.options[key]: 
       listbox.insert(END, item) 
      listbox.bind('<<ListboxSelect>>', self.onselect) 
      self.listbox = listbox 

    def onselect(self, event): 
     for lb in self.listboxes: 
      selections = lb.curselection() 
      selections = [int(x) for x in selections] 
      self.selections[lb.key] = [self.options[lb.key][x] for x in selections] 
     print(self.selections) 


if __name__ == '__main__': # \/ 
    options = {'Brand':['Brand X','Brand Y'], 'Customer Type': ['All Buyers','New Buyers','Existing Buyers']} 
    checkList(options).mainloop() 
+0

ありがとうございました!完璧な意味合いを持つ。 – kodachrome

0

あなたが投稿したコードでは、makeWidgetsで作成された最後のListBoxのみがonselectに存在します。最小限の変更で

from tkinter import * 
from tkinter import ttk 

class checkList(Frame): 
    def __init__(self, options, parent=None): 
     Frame.__init__(self, parent) 
     self.listboxes = [] 
     self.selections = {} 
     self.makeHeader() 
     self.options = options 
     self.pack(expand=YES, fill=BOTH, side=LEFT) 
     self.makeWidgets(self.options) 

    def makeHeader(self): 
     header = ttk.Label(self,text='Please select options to limit on.') 
     header.pack(side=TOP) 
     self.header = header 

    def makeWidgets(self, options): 
     for key in self.options.keys(): 
      lbl = ttk.Label(self, text=key) 
      lbl.pack(after=self.header) 
      listbox = Listbox(self, selectmode=MULTIPLE, exportselection=0) 
      listbox.pack(side=LEFT) 
      for item in self.options[key]: 
       listbox.insert(END, item) 
      listbox.bind('<<ListboxSelect>>', self.onselect) 
      self.listboxes.append(listbox) 

    def onselect(self, event): 
     for (option, options), listbox in zip(self.options.items(), self.listboxes): 
      self.selections[option] = [options[x] for x in map(int, listbox.curselection())] 
     print(self.selections) 

if __name__ == '__main__': 
    options = {'Brand':['Brand','Brand Y'], 'Customer Type': ['All Buyers','New Buyers','Existing Buyers']} 
    checkList(options).mainloop() 

これはどちらかListBox選択が変更されるたびにselections再現しています。または、eventを使用して、ListBoxの選択が変更されたことを確認し、対応する部分をselectionsに更新することができます。ただし、これにはselectionsの初期化が必要です。

関連する問題