如何在Python3/tkinter中创建一个带有3个框架和动态布局的简单窗口?

2024-03-28 14:54:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在探索Python3中的tkinter,并且刚刚开始了我的第一个GUI项目。我尝试使用网格定位系统和3个框架来创建一个简单的布局,如下所示:

  • 顶部框架:工具栏,一些按钮,可能是一个搜索字段(应该始终可见,并粘贴在窗口顶部,从左到右扩展)。在
  • 主框架:treeview,用于从数据库中检索值(应坚持在顶部,顶部框架的右下方,从左到右展开,还应展开以占据顶部和底部框架左侧的所有空间)。在
  • 底部框架:数据输入表单,状态栏。。。(应贴在窗口底部,从左向右展开,并留出空间给主框架。在

我一直在搞架子和重量,似乎总是出问题。如果主框架的尺寸足够小,则将其部分隐藏。如果我放大窗口,主框架和树视图不会按预期一直向下展开。谁能帮忙吗?在

这是我现在的代码:

#!/usr/local/bin/python3
# encoding: utf-8
"""
docstring
"""

import sys
import os
import os.path
import csv
import re
from platform import node


from tkinter import *
from tkinter import ttk


__app_name__ = "APP NAME"
__version__ = "0.0.1"


def add_remessa():
    pprint("REMESSA")


def click_btn_hoje():
    print("HOJE")


root = Tk()
root.title(__app_name__+" "+__version__)
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)

topframe = ttk.Frame(root, padding="3 3 12 12")
topframe.grid(column=0, row=0, sticky=(N, E, W))
topframe.columnconfigure(0, weight=1)
topframe.columnconfigure(1, weight=1)
topframe.rowconfigure(0, weight=1)
topframe.rowconfigure(0, weight=1)

mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=1, sticky=(N, W, E))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

bottomframe = ttk.Frame(root, padding="3 3 12 12")
bottomframe.grid(column=0, row=2, sticky=(W, E, S))
bottomframe.columnconfigure(0, weight=1)
bottomframe.columnconfigure(1, weight=1)
bottomframe.rowconfigure(0, weight=1)
bottomframe.rowconfigure(0, weight=1)


def NovaRemessa():
    print("Nova remessa!")
def EditarRemessa():
    print("Editar")
def About():
    print("This is a simple example of a menu")
def painelAddRemessa():
        print("Mostrar painel de introdução de nova remessa")


btn_quit = ttk.Button(topframe, text="+", command=painelAddRemessa)
btn_quit.grid(row=0, column=6, sticky=E+N)

btn_quit = ttk.Button(topframe, text="  Sair  ", command=exit)
btn_quit.grid(row=0, column=1, sticky=E+N)

# Data entry form
obj_num = StringVar()
destin = StringVar()
cobr = StringVar()
dias = StringVar()
vols = StringVar()

ttk.Label(bottomframe, text="Nº Objeto").grid(row=5, column=0, sticky=W+S)
text_input_obj = ttk.Entry(bottomframe,textvariable=obj_num, width=13)
text_input_obj.grid(row=6, column=0, sticky=W+S)
text_input_obj.focus_set()

ttk.Label(bottomframe, text="Destinatário").grid(row=5, column=1, columnspan=1, sticky=W+S)
text_input_dest = ttk.Entry(bottomframe, textvariable=destin, width=25)
text_input_dest.grid(row=6, column=1, sticky=W+S)

ttk.Label(bottomframe, text="Cobrança").grid(row=5, column=2, sticky=W+E+S)
text_input_cobr = ttk.Entry(bottomframe, textvariable=cobr, width=7)
text_input_cobr.grid(row=6, column=2, sticky=W+E+S)

ttk.Label(bottomframe, text="Dias").grid(row=5, column=3, sticky=W+E+S)
text_input_dias = ttk.Entry(bottomframe, textvariable=dias, width=4)
text_input_dias.grid(row=6, column=3, sticky=W+E+S)

ttk.Label(bottomframe, text="Volumes").grid(row=5, column=4, sticky=W+E+S)
text_input_vols = ttk.Entry(bottomframe, textvariable=vols, width=5)
text_input_vols.grid(row=6, column=4, sticky=W+E+S)

# Botões
btn_add = ttk.Button(bottomframe, text="  Adicionar  ", command=add_remessa).grid(row=6, column=6,sticky=W+E+S)


ttk.Label(mainframe, text="Nº de remessas: XXXX").grid(row=2, column=0, columnspan=2, sticky=W)
ttk.Label(mainframe, text="Valor a cobrar: XXXXXX").grid(row=2, columnspan=2, column=2)
ttk.Label(mainframe, text="Recebido: XXXXX").grid(row=2, column=4)
ttk.Label(mainframe, text="Depositar: XXXXXXX").grid(row=2, column=6, sticky=E)

tree = ttk.Treeview(mainframe, selectmode='extended')
tree['columns'] = ('ID', 'Dias', 'Destinatário', 'Estado', 'Objeto nº', 'Cobr.', 'Chq.rec.', 'Depositar')
tree.grid(row=0, column=0, columnspan=7, sticky=N+W+E+S)
tree.column('#0', anchor=W, minwidth=0, stretch=0, width=0)
tree.column('ID', anchor=W, minwidth=30, stretch=1, width=30)
tree.column('Dias', minwidth=30, stretch=1, width=30)
tree.column('Destinatário', minwidth=100, stretch=1, width=200)
tree.column('Estado', minwidth=100, stretch=1, width=180)
tree.column('Objeto nº', minwidth=50, stretch=1, width=80)
tree.column('Cobr.', minwidth=60, stretch=1, width=60)
tree.column('Chq.rec.', minwidth=80, stretch=1, width=80)
tree.column('Depositar', anchor=E, minwidth=80, stretch=1, width=80)
tree.heading('ID', text="ID")
tree.heading('Dias', text="Dias")
tree.heading('Destinatário', text="Destinatário")
tree.heading('Estado', text="Estado")
tree.heading('Objeto nº', text="Objeto nº")
tree.heading('Cobr.', text="Cobr.")
tree.heading('Chq.rec.', text="Chq.rec.")
tree.heading('Depositar', text="Depositar")

for child in mainframe.winfo_children(): child.grid_configure(padx=1, pady=1)

mainloop()

Tags: text框架treeinputcolumnwidthlabelgrid
1条回答
网友
1楼 · 发布于 2024-03-28 14:54:34

你忽略了几件事。首先,将所有权重赋给根窗口的第0行。因为您希望主区域占据所有额外的空间,所以需要将权重赋予第1行。在

第二,没有给主框架内的行和列赋予任何权重。因为您希望树(我假设)填充空间,所以必须给树的行和列赋予一个权重。在


一句忠告:不要试图同时解决所有的布局问题。重新启动程序,在根目录中只创建三个框架:顶部、中部和底部。暂时给他们每个人一个独特的颜色,以便你可以区分他们。然后,用包或网格来布置它们,并确保在调整窗口大小时,这些区域适当地增长和收缩。在

只有在这三个区域正常工作之后,才应该尝试只向其中一个框架添加小部件。当你调整窗口大小时,确保一切都能继续工作。然后添加下一个帧,再次确保它在继续下一个问题之前都正常工作。在

您还应该考虑将pack用于部分GUI。pack可以说是一个更好的选择,当你有东西从上到下或从一边到另一边。如果我在写这段代码,我会在三个主框架中使用pack,而在每个框架中使用grid。在

相关问题 更多 >