【问题标题】:tkinter - resize text widget (sizegrip for text widget)tkinter - 调整文本小部件的大小(文本小部件的 sizegrip)
【发布时间】:2017-11-25 21:51:40
【问题描述】:

我的目标是拥有一个“sizegrip 小部件”,使用户能够调整文本小部件的大小。

图片说明:(我为糟糕的网格道歉)

是否可以让 sizegrip 小部件调整文本小部件而不是根窗口的大小?

是否有适合我需要的替代小部件?

【问题讨论】:

  • HI 应该是可能的,但可能并不容易。您希望文本小部件下方的小部件会发生什么?
  • 他们只会向下移动。想象一下文本小部件的高增长。我实际上并不关心调整文本小部件的宽度。实际上现在我想了想,如果你只能调整文本小部件的高度,我可能会更好。
  • “他们只会向下移动” - 如果没有多余的空间怎么办?为什么不设计 UI,以便在调整窗口大小时,文本小部件会增长?
  • 它们将被推到根窗口的视图之外。图片来说明我在说什么:gyazo.com/a1760ffceb881d7f34aad1b69451f109
  • 我想你可以使用bind 来做到这一点,但 imo 会相当复杂。如您可以将Text 稍微放在Frame 垫中,然后bind 鼠标单击该填充中的一个函数,该函数根据鼠标的相对位置修改Textheightwidth .

标签: python tkinter


【解决方案1】:

如果你真的想这样做,这里有一个示例,它使用place 来管理包含文本小部件、滚动条和大小手柄的框架。如果您删除默认绑定并为 sizegrip 提供新绑定,那么您可以阻止它更改顶层几何图形并使其执行其他操作。 请注意,一两个窗格窗口是此类事物更正常的 UI 设计。

import sys
import tkinter as tk
import tkinter.ttk as ttk

class App(ttk.Frame):
    def __init__(self, parent, title=None):
        super().__init__(parent)
        parent.wm_geometry("600x400")
        parent.wm_title(title)
        self.top = tk.Frame(self, height=100, background="green4")
        self.middle = tk.Frame(self, background="red4")
        self.lower = tk.Frame(self, height=100, background="blue4")

        self.textframe = ttk.Frame(self.middle)
        self.text = tk.Text(self.textframe)
        self.vs = ttk.Scrollbar(self.textframe,
                                command=self.text.yview)
        self.sg = ttk.Sizegrip(self.textframe)
        self.text.configure(yscrollcommand=self.vs.set)
        self.text.grid(row=0, column=0, sticky="news")
        self.vs.grid(row=0, column=1, sticky="news")
        self.sg.grid(row=1, column=1, sticky="sew")
        self.textframe.grid_rowconfigure(0, weight=1)
        self.textframe.grid_columnconfigure(0, weight=1)
        self.middle.bind('<Map>', self.Place)

        self.sg.bindtags((self.sg, '.','all'))
        self.sg.bind('<Button-1>', self.Press)
        self.sg.bind('<B1-Motion>', self.Drag)
        self.sg.bind('<ButtonRelease-1>', self.Release)

        self.top.grid(row=0, column=0, sticky="news")
        self.middle.grid(row=1, column=0, sticky="news")
        self.lower.grid(row=2, column=0, sticky="news")
        self.grid_rowconfigure(1, weight=1)
        self.grid_columnconfigure(0, weight=1)
        self.grid(row=0,column=0, sticky="news")
        parent.grid_rowconfigure(0, weight=1)
        parent.grid_columnconfigure(0, weight=1)

    def Press(self, ev):
        self.dragging=True
        self.dragpos = (ev.x_root, ev.y_root)

    def Drag(self, ev):
        if self.dragging:
            dx = ev.x_root - self.dragpos[0]
            dy = ev.y_root - self.dragpos[1]
            sgx = self.sg.winfo_x() + dx
            sgy = self.sg.winfo_y() + dy
            sgw = self.sg.winfo_reqwidth()
            sgh = self.sg.winfo_reqheight()
            max_w = self.middle.winfo_width() - sgw
            max_h = self.middle.winfo_height() - sgh
            if sgx < 0 or sgx > max_w or sgy < 0 or sgy > max_h:
                return
            self.textframe.place(x=0, y=0,
                            width=sgx+sgw, height=sgy+sgh)
            self.dragpos = (ev.x_root, ev.y_root)

    def Release(self, ev):
        self.dragging=False

    def Place(self, ev):
        """Place the text widget controls once the rest of the
        application has been mapped so we actually have a size
        to work from.
        Reset the Map event to avoid re-calling this code."""
        self.textframe.bind('<Map>', None)
        self.textframe.place(x=0, y=0,
                             width=self.middle.winfo_width(),
                             height=self.middle.winfo_height())

def main(args=None):
    root = tk.Tk()
    app = App(root, "Sizegrip demo")
    root.mainloop()
    return 0

if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))

结果:

【讨论】:

  • 在 tkinter 应用程序中将位置与网格混合不是一个坏主意吗?难道只有借助网格就不能达到同样的目的吗?
  • 没有。为同一个小部件混合几何管理器是一个问题。在这里,textframe 的子项是网格化的,所有主框架(顶部、中间、下部)都是网格化的。但中框的孩子专用所用。只是有必要避免在中间的孩子上使用网格。您可以使用网格并操纵每个单元格的权重参数以达到类似的效果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-21
  • 2012-08-27
  • 2017-12-29
  • 2011-05-18
  • 1970-01-01
相关资源
最近更新 更多