2017-07-02 83 views
2

我想在tkinter中使用網格方法來顯示我在數據庫中的一些數據。當我定義__init__方法時,我必須設置特定數量的行,它們彼此相似。但是,由於行的值將來自數據庫,因此我無法準確定義我需要的行數。tkinter網格中的行

到目前爲止,我唯一的解決方案是在__init__方法中設置最大行數,我可以控制該方法。但是這個解決方案並沒有顯示屏幕上的所有信息。任何幫助將受到歡迎。

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
#------------------------------------------------------------ 

__title__= 'Control' 
__date__ = '02/07/2017' 
__version__ = '0.0.1' 

from tkinter import * 
from tkinter import ttk 

class Panel(): 
    def __init__(self): 

     self.root = Tk() 
     self.root. title('Control V' + __version__) 
     self.root.geometry('500x400') 
     self.root.configure(bg='beige') 
     self.root.minsize(400,300) 

     self.window = ttk.Frame(self.root, borderwidth=2, relief="raised", 
           padding=(10,10)) 
     self.window.grid(column=0, row=0) 
     self.window.option_add("*Font", "Helvetica 12") 

     # Row 0 
     self.r0c0 = ttk.Label(self.window, text="Header", padding=(1,1)) 
     self.r0c0.grid(row=0, column=0, columnspan=3) 

     # Row 1 
     counter = 1 
     # From db : o = {'Name': 'Zara', 'Age': 7, 'Class': 'First'} 
     o = {'Name': 'Zara', 'Age': 7, 'Class': 'First'} 

     self.r1c0 = ttk.Label(self.window, text=o['Name'], padding=(1,1)) 
     self.r1c0.grid(row=1, column=0) 
     self.r1c1 = ttk.Label(self.window, text=o['Age'], padding=(1,1)) 
     self.r1c1.grid(row=1, column=1) 
     self.r1c2 = ttk.Label(self.window, text=o['Class'], padding=(1,1)) 
     self.r1c2.grid(row=1, column=2) 

     # Row 2, Row 3, ... All are similar to Row 1 
     counter = 2 
     # From db : o = {'Name': 'Ezra', 'Age': 5, 'Class': 'First'} 
     o = {'Name': 'Ezra', 'Age': 5, 'Class': 'First'} 

     self.r2c0 = ttk.Label(self.window, text=o['Name'], padding=(1,1)) 
     self.r2c0.grid(row=2, column=0) 
     self.r2c1 = ttk.Label(self.window, text=o['Age'], padding=(1,1)) 
     self.r2c1.grid(row=2, column=1) 
     self.r2c2 = ttk.Label(self.window, text=o['Class'], padding=(1,1)) 
     self.r2c2.grid(row=2, column=2) 

     # Row 3, Row 4, ... All are similar to Row 1 & 2. 
     # Can I make a loop where n is unknown at definition 

     # All set 
     self.root.mainloop() 

def main(): 
    my_panel = Panel() 
    return 0 

if __name__ == '__main__': 
    main() 
+0

你在喜歡你的'__init__'獲得DB數據在這裏做過? – TrakJohnson

+1

你是否真的需要保持對所有這些標籤的引用?如果是這樣,你應該將它們保存在某種集合中,例如列表的列表中,而不是爲每個標籤賦予一個單獨的名稱。 –

+1

我認爲@PM2Ring爲創建顯示的每一行和列的屬性(比如'self.r1c0','self.r1c1'等)提供了一個很好的觀點。如果代碼的其他部分會變得多少,那麼代碼的其餘部分如何知道它們是什麼?在博客文章中提醒我一些建議[** _將數據保留在變量名稱_ **之外](https://nedbatchelder.com/blog/201112/keep_data_out_of_your_variable_names.html)。 – martineau

回答

1

內置enumerate功能讓您遍歷序列,並同時獲得序列項和順序索引號。默認情況下,索引從零開始,但您可以提供備用的起始索引。

爲了使代碼更易於閱讀,我已將標籤創建和打包代碼放入單獨的方法中。

import tkinter as tk 
from tkinter import ttk 

class Panel: 
    def __init__(self, field_names, database): 
     self.root = tk.Tk() 

     self.window = ttk.Frame(self.root, borderwidth=2, 
      relief="raised", padding=(10,10)) 
     self.window.grid() 

     # Create the header row 
     for col, field_name in enumerate(field_names): 
      self.add_field(field_name, 0, col, background='#ccf') 

     # Create the data rows 
     for row, record in enumerate(database, 1): 
      for col, field_name in enumerate(field_names): 
       self.add_field(record[field_name], row, col) 

     self.root.mainloop() 

    def add_field(self, value, row, col, background=''): 
     label = ttk.Label(self.window, text=value, background=background, 
      borderwidth=1, relief="raised", padding=(1,1)) 
     label.grid(row=row, column=col, sticky='ew') 


def main(): 
    field_names = ('Name', 'Age', 'Class') 

    database = [ 
     {'Name': 'Zara', 'Age': 7, 'Class': 'First'}, 
     {'Name': 'Ezra', 'Age': 5, 'Class': 'First'}, 
     {'Name': 'Amy', 'Age': 6, 'Class': 'Second'}, 
     {'Name': 'David', 'Age': 10, 'Class': 'Third'}, 
    ] 

    my_panel = Panel(field_names, database) 

if __name__ == '__main__': 
    main() 
+0

謝謝。這就是我一直在尋找的東西。現在我必須執行它。謝謝 – ogeretal

1

顯示在GUI tkinter可變數目的東西通常用Scrollbar,其可附接至ListboxCanvasText,或Entry窗口小部件來處理。在這種情況下,Listbox似乎是適當所以這裏是使用它的一個例子:

__title__= 'Control' 
__date__ = '02/07/2017' 
__version__ = '0.0.1' 

from itertools import cycle 
from tkinter import * 
from tkinter import ttk 

# Some test data 
db = [ 
    {'Name': 'Zara', 'Age': 7, 'Class': 'First'}, 
    {'Name': 'Ezra', 'Age': 5, 'Class': 'First'}, 
    {'Name': 'Bob', 'Age': 8, 'Class': 'Third'}, 
    {'Name': 'Mary', 'Age': 6, 'Class': 'Second'}, 
] 

class Panel(): 
    def __init__(self): 
     self.root = Tk() 
     self.root. title('Control V' + __version__) 
     self.root.geometry('500x400') 
     self.root.configure(bg='beige') 
     self.root.minsize(400,300) 

     self.window = ttk.Frame(self.root, borderwidth=2, relief="raised", 
           padding=(10,10)) 
     self.window.grid(column=0, row=0) 
     self.window.option_add("*Font", "Helvetica 12") 

     self.listbox = Listbox(self.window) 
     self.listbox.grid(row=0, column=0, sticky=N+E+S+W) 

     self.scrollbar = Scrollbar(self.window) 
     self.scrollbar.grid(row=0, column=1, sticky=N+S) 

     self.listbox.config(yscrollcommand=self.scrollbar.set) 
     self.scrollbar.config(command=self.listbox.yview) 

     # Row 0 
     self.listbox.insert(END, "Header") 

     # Simulate getting many rows from database by repeating them 
     endless_data = cycle(db) 
     for i in range(20): 
      row = next(endless_data) 
      line = '{Name:5} {Age:2} {Class}'.format(**row) 
      self.listbox.insert(END, line) 

     # All set 
     self.root.mainloop() 

def main(): 
    my_panel = Panel() 

if __name__ == '__main__': 
    main() 

這是什麼樣子:

screenshot of listbox

+0

謝謝,我沒有想到滾動條,因爲它只顯示一定數量的行。但它表明我有一條路要走。 – ogeretal