首页 > 解决方案 > 如何在 MultiListbox 中添加标签

问题描述

我想使用 Multilistbox 和 Label 创建一个表。我有一些代码,我尝试了很多次。但我不知道我该怎么做。在我的表格中,我希望第一行中的三行和六列将包含一列,第二行将包含 3 列,第三行将包含六列。

我的代码是这样工作的: 截屏

我的期望是这样的: 所需的图形用户界面

from tkinter import *


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)
        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)


if __name__ == '__main__':
    tk = Tk()
    Label(tk, text='MultiListbox').pack()
    mlb = MultiListbox(tk, (('Quantity', 20), ('Price', 20), ('Quantity', 20), ('Price', 20),('Quantity', 20), ('Price', 20),))
    mlb.pack(expand=YES, fill=BOTH)
    tk.mainloop()

标签: pythontkinter

解决方案


对我来说,使用grid在你的类中组织小部件MultiListbox而不是pack. 这里有一点改变是如何输入您的产品名称:

from tkinter import *

class MultiListbox(Frame):
    def __init__(self, master, lists):
        Frame.__init__(self, master)
        self.lists = []
        Label(self,text="Product Name",borderwidth=1,
              relief=RAISED).grid(row=0,column=0,columnspan=6,sticky="ew")
        for num, i in enumerate(("Product One","Product Two","Product Three"),0):
            Label(self,text=i,borderwidth=1,
              relief=RAISED).grid(row=1,column=num*2,columnspan=2,sticky="ew")
        for num, (l, w) in enumerate(lists):
            frame = Frame(self)
            frame.grid(row=2,column=num)
            Label(frame, text=l, borderwidth=1, relief=RAISED).grid(row=0,column=0,sticky="ew")
            lb = Listbox(frame, width=w, borderwidth=0, selectborderwidth=0,
                         relief=FLAT, exportselection=FALSE)
            lb.grid(row=1,column=0)
            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))
        Label(self, borderwidth=1, relief=RAISED, text=" ").grid(row=0,column=7,sticky="nesw",rowspan=3)
        sb = Scrollbar(self, orient=VERTICAL)
        sb.grid(row=2,column=7,sticky="ns")
        self.lists[0]['yscrollcommand'] = sb.set

if __name__ == '__main__':
    tk = Tk()
    Label(tk, text='MultiListbox').pack()
    mlb = MultiListbox(tk, (('Quantity', 20), ('Price', 20), ('Quantity', 20), ('Price', 20),('Quantity', 20), ('Price', 20),))
    mlb.pack(expand=YES, fill=BOTH)
    tk.mainloop()

推荐阅读