在tkinter网格中的行

时间:2017-07-02 12:34:40

标签: python tkinter grid

我想在tkinter中使用网格方法来显示我在数据库中的一些数据。当我定义__init__方法时,我必须设置特定数量的行,这些行彼此相似。但是,由于行的值将从数据库中获取,我无法准确定义我需要的行数。

到目前为止,我唯一的解决方案是在__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()

2 个答案:

答案 0 :(得分:1)

内置的enumerate函数允许您遍历序列并获取序列项和顺序索引号。默认情况下,索引从零开始,但您可以提供备用起始索引。

为了使代码更易于阅读,我已将Label创建和打包代码放入单独的方法中。

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

答案 1 :(得分:1)

tkinter GUI中显示可变数量的内容通常由Scrollbar处理,可以附加到ListboxCanvasTextEntry小部件。在这种情况下,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