消息小部件未使用 tkinter 填充框架



我正在创建一个简单的用户对话框窗口,顶部有一个基本文本,下面是一个树视图,下面有一列,为用户提供了几个选择。底部的按钮用于确认选择。

现在我无法获得用于显示说明的消息小部件来填充我为其创建的框架。同时,树视图小部件会按照我想要的方式填充框架。

许多关于其他StackOverflow问题的解决方案都指出,放my_message.pack(fill=tk.X, expand=True)应该有效。就我而言,它没有。在不同的情况下,建议放my_frame.columnconfigure(0, weight=1),这也无济于事。

这是代码:

import tkinter as tk
from tkinter import ttk
class MessageBox(object):
""" Adjusted code from StackOverflow #10057662. """
def __init__(self, msg, option_list):
root = self.root = tk.Tk()
root.geometry("400x400")
root.title('Message')
self.msg = str(msg)
frm_1 = tk.Frame(root)
frm_1.pack(expand=True, fill=tk.X, ipadx=2, ipady=2)
message = tk.Message(frm_1, text=self.msg)
message.pack(expand=True, fill=tk.X) # <------------------------------------ This doesn't show the desired effect!
frm_1.columnconfigure(0, weight=1)
self.tree_view = ttk.Treeview(frm_1)
self.tree_view.heading("#0", text="Filename", anchor=tk.CENTER)
for idx, option in enumerate(option_list):
self.tree_view.insert("", idx+1, text=option)
self.tree_view.pack(fill=tk.X, padx=2, pady=2)

choice_msg = "Long Test string to show, that my frame is unfortunately not correctly filled from side to side, as I would want it to."
choices = ["Test 1", "Test 2", "Test 3"]
test = MessageBox(choice_msg, choices)
test.root.mainloop()

我慢慢发疯了,因为我知道可能有一些非常基本的东西推翻了小部件的正确定位,但我一直在尝试不同的 StackOverflow 解决方案并浏览文档几个小时,但没有运气。

尝试在tk.Message构造函数中设置message的宽度,如下所示:

message = tk.Message(frm_1, text=self.msg, width=400-10)  # 400 - is your window width
message.pack()  # In that case you can delete <expand=True, fill=tk.X>

您面临的问题是一个功能:Message小部件尝试以以下两种方式之一布置文本:

  • 根据aspect(以百分比表示的宽高比(
  • 根据最大width(如果更长,线路将被打破(

这两个目标似乎都不能很好地配合从gridpack布局管理器自动调整Message小部件大小的体验。可以做的是将处理程序绑定到小部件的 resize 事件,以动态调整width选项。此外,与pack布局管理器一起使用的选项比 OP 中显示的更好。

我派生了一个AutoMessage小部件来消除事件处理程序:

import tkinter as tk
from tkinter import ttk

class AutoMessage(tk.Message):
"""Message that adapts its width option to its actual window width"""
def __init__(self, parent, *args, **options):
tk.Message.__init__(self, parent, *args, **options)
# The value 4 was found by experiment, it prevents text to be
# displayed outside of the widget (exceeding the right border)
self.padx = 4 + 2 * options.get("padx", 0)
self.bind("<Configure>", self.resize_handler)
def resize_handler(self, event):
self.configure(width=event.width - self.padx)

class MessageBox(object):
"""Adjusted code from StackOverflow #10057662."""
def __init__(self, msg, option_list):
root = self.root = tk.Tk()
root.geometry("400x400")
root.title("Message")
self.msg = str(msg)
self.frm_1 = tk.Frame(root)
self.frm_1.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)
self.message = AutoMessage(self.frm_1, text=self.msg, anchor=tk.W)
self.message.pack(side=tk.TOP, fill=tk.X)
self.frm_1.columnconfigure(0, weight=1)
self.tree_view = ttk.Treeview(self.frm_1)
self.tree_view.heading("#0", text="Filename", anchor=tk.CENTER)
for idx, option in enumerate(option_list):
self.tree_view.insert("", idx + 1, text=option)
self.tree_view.pack(fill=tk.X, padx=2, pady=2)

choice_msg = "Long Test string to show, that my frame is unfortunately not correctly filled from side to side, as I would want it to."
choices = ["Test 1", "Test 2", "Test 3"]
test = MessageBox(choice_msg, choices)
test.root.mainloop()

最新更新