繁体   English   中英

刷新 Python tkinter TreeView

[英]Refresh Python tkinter TreeView

我正在创建一个与 Postgresql 数据库交互的 GUI。 程序启动时,GUI 会显示某个表的所有内容。 我有一个按钮,用于添加/删除条目。 这些按钮在我检查数据库时起作用,条目被添加到数据库中,但我不知道如何刷新 TreeView 以使其反映数据库中的更改。

我尝试刷新它是清除(也构建)TreeView 是 _build_tree... 代码如下:

def _build_tree(self):
            for i in self.tree.get_children():
                self.tree.delete(i)

            for col in self.header:
                self.tree.heading(col, text=col.title(),command=lambda c=col: self.sortby(self.tree, c, 0))
                # adjust the column's width to the header string
                self.tree.column(col,width=tkFont.Font().measure(col.title()))

            for item in self.content:
                self.tree.insert('', 'end', values=item)
                # adjust column's width if necessary to fit each value
                for ix, val in enumerate(item):
                    col_w = tkFont.Font().measure(val)
                    if self.tree.column(self.header[ix],width=None)<col_w:
                        self.tree.column(self.header[ix], width=col_w)

我的完整代码如下:

from tkinter import *
import tkinter.font as tkFont
import tkinter.ttk as ttk
import datetime
import psycopg2 as pg2


myFont = ('Impact',24)
myFontColor = 'red'

def check(): #to check if button works
    print ("It works!")

class Database:
    def __init__(self):
        self.conn = pg2.connect(database='inventory', user='loremipsum', password='loremipsum')
        self.cur = self.conn.cursor()
        self.timeNow = datetime.datetime.now()

    def view_rooms(self):
        self.cur.execute('''
                    SELECT * FROM rooms
                    ORDER BY room_id;
                    ''')
        return self.cur.fetchall()

    def add_room(self,roomID,roomName,floor):
        addRoom = '''
                INSERT INTO rooms (room_id,room_name,floor)
                VALUES ({},'{}',{});
                '''.format(roomID,roomName,floor)
        self.cur.execute(addRoom)
        self.conn.commit()

    def del_room(self,roomID):
        addRoom = '''
                DELETE FROM rooms
                WHERE room_id={};
                '''.format(roomID)
        self.cur.execute(addRoom)
        self.conn.commit()

    def __del__(self):
        self.conn.close()

database = Database()

class Page(Frame):
    def __init__(self, *args, **kwargs):
        Frame.__init__(self, *args, **kwargs)
    def show(self):
        self.lift()

class RoomPage(Page):
    def __init__(self, *args, **kwargs): #create widgets
        Page.__init__(self, *args, **kwargs)

        Label(self,text="ROOM",font=myFont,fg=myFontColor).grid(row=0,column=0, sticky=W)
        Button(self,text="SEARCH",command=check).grid(row=0,column=1, sticky=W+E)

        self.header = ['Room ID','Room','Floor']
        self.content = database.view_rooms()

        self.tree=ttk.Treeview(self,columns=self.header, show="headings")
        vsb = ttk.Scrollbar(self,orient="vertical",command=self.tree.yview)
        hsb = ttk.Scrollbar(self,orient="horizontal",command=self.tree.xview)
        self.tree.configure(yscrollcommand=vsb.set,xscrollcommand=hsb.set)
        self.tree.bind('<ButtonRelease-1>',self.get_selected_row)
        self.tree.grid(column=0, row=1, columnspan=4, sticky='nsew')
        vsb.grid(column=4, row=1, sticky='ns')
        hsb.grid(column=0, row=2, columnspan=4, sticky='ew')

        self._build_tree()

        Button(self,text="ADD",command=AddRoom).grid(row=2,column=0,sticky=W+E)
        Button(self,text="REMOVE",command=self.deleteRoom).grid(row=2,column=1, sticky=W+E)
        Button(self,text="CLOSE",command=root.destroy).grid(row=2,column=3, sticky=W+E)

    def _build_tree(self):
        for i in self.tree.get_children():
            self.tree.delete(i)

        for col in self.header:
            self.tree.heading(col, text=col.title(),command=lambda c=col: self.sortby(self.tree, c, 0))
            # adjust the column's width to the header string
            self.tree.column(col,width=tkFont.Font().measure(col.title()))

        for item in self.content:
            self.tree.insert('', 'end', values=item)
            # adjust column's width if necessary to fit each value
            for ix, val in enumerate(item):
                col_w = tkFont.Font().measure(val)
                if self.tree.column(self.header[ix],width=None)<col_w:
                    self.tree.column(self.header[ix], width=col_w)

    def sortby(self,tree, col, descending):
        """sort tree contents when a column header is clicked on"""
        # grab values to sort
        data = [(tree.set(child, col), child) \
            for child in tree.get_children('')]
        # now sort the data in place
        data.sort(reverse=descending)
        for ix, item in enumerate(data):
            tree.move(item[1], '', ix)
        # switch the heading so it will sort in the opposite direction
        tree.heading(col, command=lambda col=col: sortby(tree, col, \
            int(not descending)))

    def get_selected_row(self,event):
        selection = self.tree.item(self.tree.selection())
        self.selected_tuple=selection['values'][0]

    def openRoom(self,event):
        index=self.roomList.curselection()[0]
        self.selected_tuple=self.roomList.get(index)[0]
        print (self.selected_tuple)

    def deleteRoom(self):
        database.del_room(self.selected_tuple)
        self.clear()
        self.build()

class AddRoom:
    def __init__(self, *args, **kwargs): #create widgets
        window = Toplevel(root)
        window.title("Room Details")

        roomDetailsLabel = Label (window,text="Room Details",font=myFont,fg=myFontColor).grid(row=0,column=0, sticky=W,columnspan=2)

        roomNumLabel = Label(window,text="Room ID").grid(row=1,column=0, sticky=E)
        self.roomNumText = StringVar()
        roomNameEntry = Entry(window,textvariable=self.roomNumText,width=30).grid(row=1,column=1,sticky=W)

        roomNameLabel = Label(window,text="Room Name").grid(row=2,column=0, sticky=E)
        self.roomNameText = StringVar()
        roomNameEntry = Entry(window,textvariable=self.roomNameText,width=30).grid(row=2,column=1,sticky=W)

        floorLabel = Label(window,text="Floor").grid(row=3,column=0, sticky=E)
        self.floorText = StringVar()
        floorEntry = Entry(window,textvariable=self.floorText,width=30).grid(row=3,column=1,sticky=W)

        Button(window,text="SAVE",command=self.add_room).grid(row=4,column=0,sticky=W+E)
        Button(window,text="CLOSE",command=window.destroy).grid(row=4,column=1,sticky=W+E)

    def add_room(self):
        database.add_room(self.roomNumText.get(),self.roomNameText.get(),self.floorText.get())
        p1._build_tree()

class MainView(Frame):
    def __init__(self, *args, **kwargs):
        global p1
        Frame.__init__(self, *args, **kwargs)
        p1 = RoomPage(self)

        buttonframe = Frame(self)
        container = Frame(self)
        buttonframe.pack(side="top", fill="x", expand=False)
        container.pack(side="top", fill="both", expand=True)

        p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)

        p1.show()

if __name__ == "__main__": #main loop
    root = Tk()
    root.title('Inventory System')
    root.configure(bg="#BDE9EB")
    parent = Frame(root, padx=10, pady=10)
    parent.pack(fill=BOTH, expand=True)
    main = MainView(parent)
    main.pack(side="top", fill="both", expand=True)
    root.wm_geometry("600x350")
    root.mainloop()

如何刷新 TreeView 以反映在数据库中所做的更改?

这不是刷新,但是您可以扩展将新值插入数据库的methot,并将其也插入到Treeview中。

如果仅运行建议的_build_tree方法,程序将执行什么操作?

您好,您遇到的问题似乎和我的一样。

当你调用 get.children() 之后你会做的是再次调用数据库时,你是正确的。 这是我的代码,我希望你能得到这个。

def _build_tree(self):
    cursor=db.cursor(buffered=True)
    cursor.execute("SELECT   ")
    result = cursor.fetchall()
    for i in self.tree.get_children():
           self.tree.delete(i)
    for i in result:
           self.tree.insert('', 'end', values=(i[0],i[2]..)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM