首页 > 解决方案 > 如何在 Multilistbox 中隐藏一列

问题描述

我有一个多列表框。它有三列。第一栏名称是代码编号。第二栏名称是详细信息,第三栏名称是金额。我想隐藏第一列。对于隐藏列,我在第 32 行代码中使用 .grid_remove()方法。此方法工作正常,但是当我使用 .grid_remove() 方法时,我无法选择我的 Multilistbox。

这是我的代码:

from tkinter import *
from tkinter.ttk import *
import tkinter as tk
import sqlite3
from tkinter import messagebox


class MultiListbox(Frame):

    def __init__(self, master, lists):
        Frame.__init__(self, master)
        self.grid(sticky="nsew")
        self.select_index = None
        i = 2
        for num, (l, w) in enumerate(lists):
            if num == 0:
                continue
            self.grid_columnconfigure(num, weight=w, uniform='fred')
            i += num
        self.grid_rowconfigure(1, weight=1)
        self.lists = []

        for num, (l, w) in enumerate(lists):
            frame = Frame(self, borderwidth=0)
            frame.grid_columnconfigure(0, weight=1)
            frame.grid_rowconfigure(1, weight=1)
            frame.grid(row=1, column=num, sticky="nsew")
            lbl = Label(frame, text=l, font=("Vrinda (Body CS)", 11), borderwidth=1, relief=SUNKEN, anchor="center", justify="center")
            lbl.grid(row=0, column=0, sticky="nsew")
            lb = Listbox(frame, font=("Vrinda (Body CS)", 9), height=5, borderwidth=1, selectborderwidth=1, exportselection=FALSE)
            lb.grid(row=1, column=0, sticky="nsew")
            if num == 0:
                frame.grid_remove()
                lbl.grid_remove()
                lb.grid_remove()

            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))
            lb.bind('&lt;Button-4>', lambda e, s=self: s._scroll(SCROLL, 1, PAGES))
            lb.bind('&lt;Button-5>', lambda e, s=self: s._scroll(SCROLL, -1, PAGES))
            lb.bind("<MouseWheel>", self.OnMouseWheel)

        sb_y = Scrollbar(self, orient=VERTICAL, command=self._yscroll)
        sb_y.grid(row=1, rowspan=2, column=i, sticky="nsew")
        self.lists[0]['yscrollcommand'] = sb_y.set

        ent_total = Entry(self, width=0, justify="center")
        ent_total.grid(row=2, column=0, columnspan=2, sticky="nesw")

        self.sum_value = StringVar(value=0)
        ent_sum_value = Entry(self, width=0, textvariable=self.sum_value)
        ent_sum_value.grid(row=2, column=2, sticky="nesw")

        sb_x = Scrollbar(self, orient=HORIZONTAL, command=self._xscroll)
        sb_x.grid(row=3, column=0, columnspan=i, sticky="ew")
        self.lists[0]['xscrollcommand'] = sb_x.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 _yscroll(self, *args):
        for l in self.lists:
            l.yview(*args)

    def _xscroll(self, *args):
        for l in self.lists:
            l.xview(*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 list(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
        self.sum_values()

    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):
        self.select_index =[first]
        for l in self.lists:
            l.selection_set(first, last)

    def sum_values(self):
        total = sum(self.lists[-1].get(0, END))
        self.sum_value.set(total)

    def OnMouseWheel(self, event):
        for l in self.lists:
            l.yview("scroll", event.delta,"units")
        # this prevents default bindings from firing, which
        # would end up scrolling the widget twice
        return "break"


class FormAddProduct:

    def __init__(self, master):
        self.frame = master
        self.frame.configure(padx=5)
        for i in range(0, 1):
            self.frame.grid_columnconfigure(i, weight=1)
        self.frame.grid_rowconfigure (1, weight = 1)
        self._init_widgets()
        self.database()

    def database(self):
        self.con = sqlite3.connect("database.db")
        self.cur = self.con.cursor()
        self.cur.execute("""
                        CREATE TABLE IF NOT EXISTS product(rowid INTEGER PRIMARY KEY,
                        code_no TEXT,
                        particulart TEXT,
                        amount NUMBER)
                        """)
        self.con.commit()

    def _init_widgets(self):
        self.frame1 = tk.Frame(self.frame, relief=FLAT, borderwidth=1)
        for i in range(0, 4):
            self.frame1.grid_columnconfigure(i, weight=1)
        for i in range(0, 3):
            self.frame1.grid_rowconfigure(i, weight=1)

        lbl = Label(self.frame1, text="Enter Item Code").grid(row=0, column=0)
        self.ent_item_code = Entry(self.frame1)
        self.ent_item_code.grid(row=0, column=1, sticky="nesw")

        self.mlb = MultiListbox(self.frame1, (
            ('Code No.', 1), ('Particulars', 3), ('Amount $', 1)))
        self.mlb.grid(row=1, column=0, columnspan=4, sticky="nsew")
        a1 =  ("A89", "Apple", 10)
        a2 = ("C20", "Orange", 25)
        a3 = ("Q97", "Banana", 25)

        self.mlb.insert(END, a1)
        self.mlb.insert(END, a2)
        self.mlb.insert(END, a3)

        self.frame1.grid(row=1, column=0, sticky="nsew", padx=1, pady=5)

        self.btn_save_item = tk.Button(self.frame1, command=self.save_item, text="Save", relief="solid", bg="white")
        self.btn_save_item.grid(row=2, column=3,  padx=1, pady=1, sticky="nsew")


    def save_item(self):
        for no_of_item in range(int(self.mlb.size())):
            item = self.mlb.get(no_of_item)
            self.cur.execute("""
                            INSERT INTO product VALUES(NULL, ?, ?, ?)""",
                             (item[0], item[1], item[2])
                             )
        try:

            self.con.commit()
            tk.messagebox.showinfo('Save', 'Saving complete.')
        except sqlite3.Error:
            self.con.rollback()
            tk.messagebox.showwarning('Save', 'An Error Occured.')

def main():
    app = Tk()
    FormAddProduct(app)
    app.mainloop()

if __name__=='__main__':
    main()

标签: tkinterpython-3.7

解决方案


推荐阅读