【问题标题】:Python - Multi Listbox to Entry boxPython - 多列表框到输入框
【发布时间】:2019-02-17 16:24:32
【问题描述】:

我正在使用多列表框的代码 (http://code.activestate.com/recipes/52266-multilistbox-tkinter-widget/)

这是为用户创建数据列以供选择,我希望当用户 Listboxselect 记录中的列填充到不同的条目框中。

我可以在函数中使用 .bind .delete .insert 使其在标准列表框中工作,但由于字典中的数据大小不同,它看起来很难看:)

我真的很想坚持使用下面的代码,但我无法让该功能正常工作。真的很感谢有人能指出我正确的方向,试图解决这个问题几天但绕圈子

我想解决的代码

def on_selection(event):
        line = event.widget.get(event.widget.curselection())

        locationent.delete(0, 'end')
        cuspnent.delete(0, 'end')
        locationent.insert('end', line[0:1])
        cuspnent.insert('end', line[1:2])


if __name__ == '__main__':
    ttk.Label(leftbottomframe, text='**Select count record from MultiListbox by doubleclick**').pack()
    mlb = MultiListbox(leftbottomframe, (('Location', 15),('RRD PN', 15),("Lot/Serial", 15), ('Description', 35), ('Customer PN', 15)))
    for i in dic:
         mlb.insert(END, (dic[i]['Location'],dic[i]['Item Number'],dic[i]['Lot/Serial'],dic[i]['Description'],dic[i]['Cross_Reference']))


    mlb.bind('<<ListboxSelect>>', on_selection)

用于多列表框的更大代码集

data_file= pd.read_excel('CC 180763.xlsx',sheet_name='Sheet1',header=0,converters={'Location':str,'Item Number':str,'Cross_Reference':str,'Description':str})

print (data_file)

dic = data_file.set_index('Reference').transpose().to_dict(orient='dict')# data_file.to_dict(orient='records')


class MultiListbox(Frame):
    def __init__(self, master, lists):
        Frame.__init__(self, master)
        self.lists = []
        for l, w in lists:
            frame = Frame(self);
            frame.pack(side=LEFT, expand=YES, fill=BOTH)
            Label(frame, text=l, borderwidth=1, relief=RAISED).pack(fill=X)
            lb = Listbox(frame, width=w, borderwidth=0, selectborderwidth=0,
                         relief=FLAT, exportselection=FALSE)
            lb.pack(expand=YES, fill=BOTH)
            self.lists.append(lb)
            lb.bind('<B1-Motion>', lambda e, s=self: s._select(e.y))
            lb.bind('<Button-1>', lambda e, s=self: s._select(e.y))
            lb.bind('<Leave>', lambda e: 'break')
            lb.bind('<B2-Motion>', lambda e, s=self: s._b2motion(e.x, e.y))
            lb.bind('<Button-2>', lambda e, s=self: s._button2(e.x, e.y))
        frame = Frame(self);
        frame.pack(side=LEFT, fill=Y)
        ttk.Label(frame, borderwidth=1, relief=RAISED).pack(fill=X)
        sb = Scrollbar(frame, orient=VERTICAL, command=self._scroll)
        sb.pack(expand=YES, fill=Y)
        self.lists[0]['yscrollcommand'] = sb.set

    def _select(self, y):
        row = self.lists[0].nearest(y)
        self.selection_clear(0, END)
        self.selection_set(row)
        return 'break'

    def _button2(self, x, y):
        for l in self.lists: l.scan_mark(x, y)
        return 'break'

    def _b2motion(self, x, y):
        for l in self.lists: l.scan_dragto(x, y)
        return 'break'

    def _scroll(self, *args):
        for l in self.lists:
            apply(l.yview, args)

    def curselection(self):
        return self.lists[0].curselection()

    def delete(self, first, last=None):
        for l in self.lists:
            l.delete(first, last)

    def get(self, first, last=None):
        result = []
        for l in self.lists:
            result.append(l.get(first, last))
        if last: return apply(map, [None] + result)
        return result

    def index(self, index):
        self.lists[0].index(index)

    def insert(self, index, *elements):
        for e in elements:
            i = 0
            for l in self.lists:
                l.insert(index, e[i])
                i = i + 1

    def size(self):
        return self.lists[0].size()

    def see(self, index):
        for l in self.lists:
            l.see(index)

    def selection_anchor(self, index):
        for l in self.lists:
            l.selection_anchor(index)

    def selection_clear(self, first, last=None):
        for l in self.lists:
            l.selection_clear(first, last)

    def selection_includes(self, index):
        return self.lists[0].selection_includes(index)

    def selection_set(self, first, last=None):
        for l in self.lists:
            l.selection_set(first, last)

def on_selection(event):
        line = event.widget.get(event.widget.curselection())

        locationent.delete(0, 'end')
        cuspnent.delete(0, 'end')
        locationent.insert('end', line[0:1])
        cuspnent.insert('end', line[1:2])


if __name__ == '__main__':
    ttk.Label(leftbottomframe, text='**Select count record from MultiListbox by doubleclick**').pack()
    mlb = MultiListbox(leftbottomframe, (('Location', 15),('RRD PN', 15),("Lot/Serial", 15), ('Description', 35), ('Customer PN', 15)))
    for i in dic:
         mlb.insert(END, (dic[i]['Location'],dic[i]['Item Number'],dic[i]['Lot/Serial'],dic[i]['Description'],dic[i]['Cross_Reference']))


    mlb.bind('<<ListboxSelect>>', on_selection)

    mlb.pack(expand=YES, fill=BOTH)

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    问题:当用户列表框选择记录中的列被填充时

    1. 删除这个,因为它绑定到Frame,这不是你想要的。

      #mlb.bind('<<ListboxSelect>>', on_selection)
      
    2. 将以下内容添加到class MultiListbox

      class MultiListbox(Frame):
          def __init__(self, master, lists):
              Frame.__init__(self, master)
              self.labels = []
              ...
              for l, w in lists:
                  self.labels.append(l)
                  lb.bind('<<ListboxSelect>>', self.on_selection)
                  ...
      
    3. 删除以下内容,因为绑定任何B1... 将阻止&lt;&lt;ListboxSelect&gt;&gt; 事件。

      注意:如果您需要这些绑定,否则您必须链接到self.on_selection

                  #lb.bind('<B1-Motion>', lambda e, s=self: s._select(e.y))
                  #lb.bind('<Button-1>', lambda e, s=self: s._select(e.y))
      
    4. 使def on_selection(... 成为class MultiListbox 的方法:

          def on_selection(self, event):
              # Get the current selected row
              row = event.widget.curselection()[0]
      
              # Clear previous selected row, select the current row
              self.selection_clear(0, END)
              self.selection_set(row)
      
              # Create a dict record from all self.lists
              # Use self.labels as dict key
              record = {}
              for column, lb in enumerate(self.lists):
                  record[self.labels[column]] = lb.get(row, row)[0]
      
              print('Selection[{}]:{}'.format(row, record))
      

    用法

            mlb = MultiListbox(leftbottomframe,
                               (('Location', 15),('RRD PN', 15),("Lot/Serial", 15),
                                ('Description', 35), ('Customer PN', 15)))
    
            for n in range(3):
                mlb.insert(END, ['{}_{}'.format(label, n) for label in mlb.labels])
    
            mlb.pack(expand=YES, fill=BOTH)
    

    输出

    Selection[0]:{'Description': 'Description_0', 'Location': 'Location_0', 'Customer PN': 'Customer PN_0', 'Lot/Serial': 'Lot/Serial_0', 'RRD PN': 'RRD PN_0'}
    Selection[1]:{'Description': 'Description_1', 'Location': 'Location_1', 'Customer PN': 'Customer PN_1', 'Lot/Serial': 'Lot/Serial_1', 'RRD PN': 'RRD PN_1'}
    Selection[2]:{'Description': 'Description_2', 'Location': 'Location_2', 'Customer PN': 'Customer PN_2', 'Lot/Serial': 'Lot/Serial_2', 'RRD PN': 'RRD PN_2'}
    

    用 Python 测试:3.5

    【讨论】:

      猜你喜欢
      • 2021-12-20
      • 1970-01-01
      • 2021-09-26
      • 2012-12-30
      • 1970-01-01
      • 2021-07-20
      • 2020-09-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多