python-3.x 消息小工具未使用tkinter填充帧

e7arh2l6  于 2023-02-26  发布在  Python
关注(0)|答案(2)|浏览(153)

我正在创建一个简单的用户对话框窗口,顶部是基本文本,下面是一个树状视图,它给用户提供了几个选择,底部的按钮用于确认选择。
现在,我无法让用来显示说明的消息小部件填充我为其创建的框架,同时,Treeview小部件可以根据我的需要填充框架。
许多针对其他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解决方案和浏览文档几个小时了,现在没有运气。

5gfr0r5j

5gfr0r5j1#

尝试在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>
jtjikinw

jtjikinw2#

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

  • 根据aspect(宽高比,以百分比表示)
  • 根据最大值width(如果更长,则会断线)

这两个目标似乎都不能很好地配合gridpack布局管理器对Message小部件的自动调整大小。可以做的是将一个处理程序绑定到小部件的resize事件,以动态调整width选项。此外,与OP中所示的相比,pack布局管理器可以使用更好的选项。
我派生了一个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()

相关问题