在3个分开的tk.Text框中显示文本的方法是什么?

huangapple go评论69阅读模式
英文:

Is there a way to display text at one level in 3 separated tk.Text boxes?

问题

I make my program with tkinter. Program stores some information in array([[aaa, bbb, ccc],[ddd, eee, fff]]) and I want to display it in 3 text boxes. The first box will contain aaa and ddd, other 2 will contain data in the same way. But I don't know how to display it on the same level, because if one of the variables contains long text, then it will be displayed in several lines, while variables from other columns will be displayed under each other without empty lines to maintain the same level.

How it works

As you can see, the text "cccc" is opposite the text "bbbbb" when it needs to be spaced across blank lines to maintain the same level.
I tried to add blank lines to the first and second columns, counting the number of displayed lines in the third column, but couldn't figure out how to do it.

Here is some code for text boxes and displaying the data:

for item in array:
    entry_ip.insert(tk.END, item[0] + "\n")
    entry_id.insert(tk.END, item[1] + "\n")
    entry_comment.insert(tk.END, item[2] + "\n")
entry_comment = Text(
    bd=0,
    bg="#FFFFFF",
    fg="#000716",
    highlightthickness=0
)
entry_comment.place(
    x=564.0,
    y=167.0,
    width=198.0,
    height=432.0
)

entry_ip = Text(
    bd=0,
    bg="#FFFFFF",
    fg="#000716",
    highlightthickness=0
)
entry_ip.place(
    x=207.0,
    y=167.0,
    width=177.0,
    height=432.0
)

entry_id = Text(
    bd=0,
    bg="#FFFFFF",
    fg="#000716",
    highlightthickness=0
)
entry_id.place(
    x=386.0,
    y=167.0,
    width=176.0,
    height=432.0
)
英文:

I make my program with tkinter. Program stores some information in array([[aaa, bbb, ccc],[ddd, eee, fff]]) and I want to display it in 3 text boxes. The first box will contain aaa and ddd, other 2 will contain data in same way. But I don't know how to display it in same level, because if one of the variables contains long text, then it will be displayed in several lines, while variables from other columns will be displayed under each other without empty lines to maintain the same level.

How it works

As you can see, the text "cccc" is opposite the text "bbbbb" when it needs to be spaced across blank lines to maintain the same level.
I tried to add blank lines to the first and second columns, counting the number of displayed lines in the third column, but couldn't figure out how to do it.
Here some code of text boxes and displaying the data.

for item in array:
    entry_ip.insert(tk.END, item[0] + "\n")
    entry_id.insert(tk.END, item[1] + "\n")
    entry_comment.insert(tk.END, item[2] + "\n")
entry_comment = Text(
    bd=0,
    bg="#FFFFFF",
    fg="#000716",
    highlightthickness=0
)
entry_comment.place(
    x=564.0,
    y=167.0,
    width=198.0,
    height=432.0
)

entry_ip = Text(
    bd=0,
    bg="#FFFFFF",
    fg="#000716",
    highlightthickness=0
)
entry_ip.place(
    x=207.0,
    y=167.0,
    width=177.0,
    height=432.0
)

entry_id = Text(
    bd=0,
    bg="#FFFFFF",
    fg="#000716",
    highlightthickness=0
)
entry_id.place(
    x=386.0,
    y=167.0,
    width=176.0,
    height=432.0
)

答案1

得分: 0

这是您提供的代码的翻译:

使用文本小部件时没有简单的解决方案原因如您在帖子中提到的那样我认为更简单的解决方案是使用标签网格唯一的真正技巧是您需要添加一个绑定以设置每个标签的 `wraplength` 属性以便当文本太长而无法容纳时标签上的文本会换行

这是创建一个小标签网格的示例
```python
import tkinter as tk

data = (
    ("aaa", "bbb", "ccc"),
    ("ddd", "eee", "一个示例,它是一个长文本示例,会换行"),
    ("ggg", "hhh", "iii"),
)

class LabelGrid(tk.Frame):
    def __init__(self, parent, data):
        super().__init__(parent)

        # 这假设只有第三列在包含框增大或缩小时才会增大或缩小。
        self.grid_columnconfigure(2, weight=1)

        for row_number, row_data in enumerate(data):
            for column_number, column_data in enumerate(row_data):
                label = tk.Label(self, width=10, text=column_data, justify="left", anchor="nw")
                label.grid(row=row_number, column=column_number, sticky="nsew")
                label.bind("<Configure>", self._reset_wraplength)

    def _reset_wraplength(self, event):
        event.widget.configure(wraplength=event.widget.winfo_width() - 2)

root = tk.Tk()
lg = LabelGrid(root, data)
lg.pack(fill="both", expand=True, padx=2, pady=2)

root.mainloop()

如果您需要能够滚动列表,可以将此框架放入画布中,因为画布支持滚动。以下示例演示了如何实现这一点,基于此处的一种技术:https://stackoverflow.com/questions/3085696/adding-a-scrollbar-to-a-group-of-widgets-in-tkinter/3092341#3092341

import tkinter as tk

data = (
    ("aaa", "bbb", "ccc"),
    ("ddd", "eee", "一个示例,它是一个长文本示例,会换行"),
    ("ggg", "hhh", "iii"),
)

class LabelGrid(tk.Frame):
    def __init__(self, parent, data):
        super().__init__(parent, bg="pink")

        # 这假设只有第三列在包含框增大或缩小时才会增大或缩小。
        self.grid_columnconfigure(2, weight=1)

        for row_number, row_data in enumerate(data):
            for column_number, column_data in enumerate(row_data):
                label = tk.Label(self, width=10, text=column_data, justify="left", anchor="nw")
                label.grid(row=row_number, column=column_number, sticky="nsew")
                label.bind("<Configure>", self._reset_wraplength)

    def _reset_wraplength(self, event):
        event.widget.configure(wraplength=event.widget.winfo_width() - 2)


class ScrollableFrame(tk.Frame):
    def __init__(self, parent):

        tk.Frame.__init__(self, parent, bg="bisque")
        self.canvas = tk.Canvas(self, borderwidth=0)
        self.frame = None
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.vsb.set)

        self.vsb.pack(side="right", fill="y")
        self.canvas.pack(side="left", fill="both", expand=True)

        self.canvas.create_window((4, 4), window=None, anchor="nw", tags=("inner_frame",))
        self.bind("<Configure>", self._reset_width)

    def set_frame(self, frame):
        self.frame = frame
        self.canvas.itemconfigure("inner_frame", window=frame)

        self.frame.lift(self.canvas)
        self.frame.bind("<Configure>", self._reset_scrollregion)

    def _reset_width(self, event):
        self.canvas.itemconfigure("inner_frame", width=event.width - 20)

    def _reset_scrollregion(self, event):
        '''Reset the scroll region to encompass the inner frame'''
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))


root = tk.Tk()
sf = ScrollableFrame(root)
sf.pack(fill="both", expand=True)

lg = LabelGrid(sf, data)
sf.set_frame(lg)

root.mainloop()

希望这些翻译对您有所帮助。如果您有任何其他问题,请随时提出。
<details>
<summary>英文:</summary>
There&#39;s no simple solution when using a text widget, for the very reasons you include in your post. I think a simpler solution would be to use a grid of labels. The only real trick is that you need to add a binding that sets the `wraplength` attribute of each label so that text on the label wraps when it is too long to fit.
Here&#39;s an example of creating a small grid of labels:

import tkinter as tk

data = (
("aaa", "bbb", "ccc"),
("ddd", "eee", "an example of a long value that wraps"),
("ggg", "hhh", "iii"),
)

class LabelGrid(tk.Frame):
def init(self, parent, data):
super().init(parent)

    # this assumes only the third column should grow or shrink
# when the containing frame grows or shrinks.
self.grid_columnconfigure(2, weight=1)
for row_number, row_data in enumerate(data):
for column_number, column_data in enumerate(row_data):
label = tk.Label(self, width=10, text=column_data, justify=&quot;left&quot;, anchor=&quot;nw&quot;)
label.grid(row=row_number, column=column_number, sticky=&quot;nsew&quot;)
label.bind(&quot;&lt;Configure&gt;&quot;, self._reset_wraplength)
def _reset_wraplength(self, event):
event.widget.configure(wraplength = event.widget.winfo_width()-2)

root = tk.Tk()
lg = LabelGrid(root, data)
lg.pack(fill="both", expand=True, padx=2, pady=2)

root.mainloop()

[![screenshot narrow window][1]][1]
If you need to be able to scroll the list, you can put this frame inside a canvas since the canvas supports scrolling. The following example shows how to do that, based on a technique seen here: https://stackoverflow.com/questions/3085696/adding-a-scrollbar-to-a-group-of-widgets-in-tkinter/3092341#3092341

import tkinter as tk

data = (
("aaa", "bbb", "ccc"),
("ddd", "eee", "an example of a long value that wraps"),
("ggg", "hhh", "iii"),
)

class LabelGrid(tk.Frame):
def init(self, parent, data):
super().init(parent, bg="pink")

    # this assumes only the third column should grow or shrink
# when the containing frame grows or shrinks.
self.grid_columnconfigure(2, weight=1)
for row_number, row_data in enumerate(data):
for column_number, column_data in enumerate(row_data):
label = tk.Label(self, width=10, text=column_data, justify=&quot;left&quot;, anchor=&quot;nw&quot;)
label.grid(row=row_number, column=column_number, sticky=&quot;nsew&quot;)
label.bind(&quot;&lt;Configure&gt;&quot;, self._reset_wraplength)
def _reset_wraplength(self, event):
event.widget.configure(wraplength = event.widget.winfo_width()-2)

class ScrollableFrame(tk.Frame):
def init(self, parent):

    tk.Frame.__init__(self, parent, bg=&quot;bisque&quot;)
self.canvas = tk.Canvas(self, borderwidth=0)
self.frame = None
self.vsb = tk.Scrollbar(self, orient=&quot;vertical&quot;, command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.vsb.set)
self.vsb.pack(side=&quot;right&quot;, fill=&quot;y&quot;)
self.canvas.pack(side=&quot;left&quot;, fill=&quot;both&quot;, expand=True)
self.canvas.create_window((4,4), window=None, anchor=&quot;nw&quot;,tags=(&quot;inner_frame&quot;,))
self.bind(&quot;&lt;Configure&gt;&quot;, self._reset_width)
def set_frame(self, frame):
self.frame = frame
self.canvas.itemconfigure(&quot;inner_frame&quot;, window=frame)
self.frame.lift(self.canvas)
self.frame.bind(&quot;&lt;Configure&gt;&quot;, self._reset_scrollregion)
def _reset_width(self, event):
self.canvas.itemconfigure(&quot;inner_frame&quot;, width=event.width-20)
def _reset_scrollregion(self, event):
&#39;&#39;&#39;Reset the scroll region to encompass the inner frame&#39;&#39;&#39;
self.canvas.configure(scrollregion=self.canvas.bbox(&quot;all&quot;))

root = tk.Tk()
sf = ScrollableFrame(root)
sf.pack(fill="both", expand=True)

lg = LabelGrid(sf, data)
sf.set_frame(lg)

root.mainloop()


[1]: https://i.stack.imgur.com/AVM13.png
</details>

huangapple
  • 本文由 发表于 2023年5月17日 07:01:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76267591.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定