画布中的 Tkinter 窗口未填充其父窗口的高度

2024-01-11

我希望我的滚动条位于框架底部,并且我的文本小部件填充滚动条上方的整个框架。我找到了一些关于宽度配置的解决方案here https://stackoverflow.com/questions/29319445/tkinter-how-to-get-frame-in-canvas-window-to-expand-to-the-size-of-the-canvas但是当我尝试用高度替换宽度时,它无法正常工作。

from tkinter import *
from tkinter import ttk

class MainView(Frame):

    def FrameHeight(self, event):
        canvas_height = event.height
        self.canvas.itemconfig(self.canvas_frame, height=canvas_height)

    def OnFrameConfigure(self, event):
        self.canvas.config(scrollregion=self.canvas.bbox("all"))

    def __init__(self, *args, **kwargs):
        Frame.__init__(self, *args, **kwargs)
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        sensorsFrame = Frame(self)
        sensorsFrame.grid(row=0, sticky="nsew")
        sensorsFrame.grid_columnconfigure(0, weight=1)
        sensorsFrame.grid_rowconfigure(0, weight=1)

        self.canvas = Canvas(sensorsFrame)
        self.sensorsStatsFrame = Frame(self.canvas)
        self.canvas.grid_rowconfigure(0, weight=1)
        self.sensorsStatsFrame.grid_rowconfigure(0, weight=1)

        myscrollbar = Scrollbar(sensorsFrame,orient=HORIZONTAL,command=self.canvas.xview)
        self.canvas.configure(xscrollcommand=myscrollbar.set)
        self.canvas.pack(fill=BOTH, expand=1)
        myscrollbar.pack(fill=X, expand=1)

        test0 = Text(self.sensorsStatsFrame, state=DISABLED)
        test1 = Text(self.sensorsStatsFrame, width=150)
        test0.grid(column=0, row=0, sticky="nsew")
        test1.grid(column=1, row=0, sticky="nsew")

        self.canvas_frame = self.canvas.create_window((0,0),window=self.sensorsStatsFrame,anchor='nw')
        self.sensorsStatsFrame.bind("<Configure>", self.OnFrameConfigure)

        #When I try to use what i found
        #self.canvas.bind('<Configure>', self.FrameHeight)

if __name__ == "__main__":
    root = Tk()
    main = MainView(root)
    main.pack(fill="both", expand=1)
    root.wm_geometry("1100x500")
    root.wm_title("MongoDB Timed Sample Generator")
    root.mainloop()

步骤 1:删除滚动条上方和下方的空间

The expand选项确定 tkinter 如何处理未分配的空间。额外的空间将平均分配给该值为的所有小部件1 or True。因为它被设置为1对于滚动条,它被给予一些额外的空间,导致小部件上方和下方的填充。

相反,您想要的是将所有空间仅分配给画布。通过设置来做到这一点expand将滚动条归零:

myscrollbar.pack(fill=X, expand=0)

第2步:当画布大小改变时调用函数

下一个问题是,当画布大小改变时,您希望内部框架变大,因此您需要绑定到<Configure>画布的事件。

def OnCanvasConfigure(self, event):
    <code to set the size of the inner frame>
...
self.canvas.bind("<Configure>", self.OnCanvasConfigure)

第三步:让画布控制内框的大小

你不能只改变内框的大小OnCanvasConfigure,因为框架的默认行为是缩小以适合其内容。在这种情况下,您希望内容扩展以适合框架,而不是缩小框架以适合内容。

有几种方法可以解决这个问题。你可以转几何传播关闭内部框架,这将防止内部小部件更改框架的大小。或者,您可以让画布强制框架的大小。

第二种解决方案是最简单的。我们所要做的就是使用画布的高度作为框架高度,并使用内部文本小部件的宽度之和作为框架宽度。

def OnCanvasConfigure(self, event):
    width = 0
    for child in self.sensorsStatsFrame.grid_slaves():
        width += child.winfo_reqwidth()

    self.canvas.itemconfigure(self.canvas_frame, width=width, height=event.height)

第四步:修复滚动条

还有一个问题需要解决。如果您调整窗口大小,您会注意到如果窗口太小,tkinter 会截断滚动条。您可以通过删除调整窗口大小的功能来解决此问题,但您的用户会讨厌这样做。

更好的解决方案是在滚动条被切断之前使文本小部件收缩。您可以通过调用顺序来控制它pack.

当没有足够的空间容纳所有小部件时,tkinter 将开始减小小部件的大小,从添加到窗口的最后一个小部件开始。在您的代码中,滚动条是最后一个小部件,但如果您将其设为画布,则滚动条将保持不变,而画布将缩小(这反过来会导致框架缩小,从而导致文本小部件缩小)。

myscrollbar.pack(side="bottom", fill=X, expand=0)
self.canvas.pack(fill=BOTH, expand=1)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

画布中的 Tkinter 窗口未填充其父窗口的高度 的相关文章

随机推荐

  • 更改 MessageBox 按钮文本的语言

    我希望 MessageBox 按钮上的文本可以是俄语 法语等 与 Windows 中默认设置的语言不同 有没有办法在不创建自定义消息框的情况下做到这一点 避免在这上面花费大量的时间和精力 您的应用程序的用户将始终看到她熟悉的消息框 它将显示
  • Angular 9平台引导多个模块——在页面上运行多个应用程序

    我正在开发一个需要在页面上运行两个应用程序的项目 就像是
  • Kubernetes 指标服务器未运行

    我已经使用 VirtualBox 在本地 k8s 集群上安装了指标服务器https github com kubernetes sigs metrics server installation https github com kubern
  • 在 zend 中哪里保存自定义自动加载器?

    我正在尝试使用phpThumb http phpthumb gxdlabs com 在我的应用程序中通过制作自定义自动加载器 class My Loader Autoloader PhpThumb implements Zend Loade
  • 二分查找中值计算

    以下是我从 TopCoder 教程中得到的关于二分搜索的伪代码 binary search A target lo 1 hi size A while lo lt hi mid lo hi lo 2 if A mid target retu
  • LIST<> AddRange 抛出 ArgumentException

    我有一个特定的方法 偶尔会因 ArgumentException 崩溃 Destination array was not long enough Check destIndex and length and the array s low
  • Android布局权重注释

    我正在尝试使用构建 Android 布局layout weight适合所有尺寸的设备 但我在理解它的功能时遇到了一些困难 我注意到改变layout width layout height影响了layout weight行为 但我不明白如何
  • 动态模拟远程用户 - c# 和 asp.net

    我想动态模拟远程用户来执行代码的某些部分 我在网上搜索了很多并得到了一些可以模拟的代码 模拟的代码如下所示 namespace Tools region Using directives using System using System
  • 如何处理多个同名的cookie?

    举例来说 我有一个应用程序发送以下 HTTP 标头以设置为名为 a 的 cookie Set Cookie a 1 Path Version 1 Set Cookie a 2 Path example Version 1 如果我访问 exa
  • 使用 boost 线程:发出信号并等待终止

    我目前正在编写一个c c dll 供以后主要在Delphi 中使用 并且我对Delphi 中的线程比c c 更熟悉 尤其是boost 所以我想知道如何实现以下场景 class CMyClass private boost thread do
  • Rust 中的线程安全可变非拥有指针?

    我正在尝试并行化我拥有的算法 这是我如何用 C 编写它的草图 void thread func std vector
  • Apache Giraph - 无法在拆分主/工作模式下运行,因为一次只有 1 个任务

    我使用 PageRank Benchmark 示例运行 Giraph 1 0 0 和 hadoop 2 2 0here https github com aching Giraph wiki Quick Start Guide 突然我得到了
  • 使用 C# 在 Excel 中复制/粘贴单元格

    如何在 Excel 文件中选择特定用户范围并复制这些单元格并插入复制的单元格Shift xlDown使用 C 这是我需要转换为 C 的 VBA 代码 Range A9 L9 Select Selection Copy Rows 10 10
  • 在三元运算符中使用 OR

    我有一个简单的三元运算符 我想用两个不同的字符串返回 null this props sportType tennis soccer null li N A li 但不幸的是 这并不完全有效 我该如何使用 在三元运算符中正确吗 谢谢 重复与
  • Android Wear 断开连接通知

    我有一个 Android Wear 应用程序 它将加速度计值传递给手持设备应用程序 当与 Android Wear 应用程序的连接刚刚丢失时 例如 当 Android Wear 应用程序关闭时 我希望在手持应用程序中收到通知 我必须如何实施
  • 在云 9IDE 中使用 Node js Express 运行 Hello World

    我通过替换使用 Node JS Express 框架在 cloud 9 IDE 中成功运行了 hello world app listen 3000 to app listen process env PORT cloud 9 要求我使用
  • 是否有一个 .NET IoC 更喜欢约定而不是配置?

    简而言之 如果您必须使用 IoC DI 容器 那么它易于部署 不热衷于使用 config xml 文件来完成所有事情 稳定 良好的文档并支持 net 您会选择哪一个 可能只是我的问题 但太多的 xml 文件 例如一个用于应用程序的文件 一些
  • 交叉连接,然后左连接

    是否可以在两个表之间进行交叉联接 然后对第三个表进行左联接 然后可能进行更多左联接 我正在使用 SQL Server 2000 2005 我正在运行以下查询 这在我看来非常简单 但我收到错误 select P PeriodID P Peri
  • 在静态 json 文件的 Node js 上使用 getJSON 时不支持获取协议

    在我的 Node js 文件中 我有以下代码 var jqxhr getJSON favs json function console log success done function console log second success
  • 画布中的 Tkinter 窗口未填充其父窗口的高度

    我希望我的滚动条位于框架底部 并且我的文本小部件填充滚动条上方的整个框架 我找到了一些关于宽度配置的解决方案here https stackoverflow com questions 29319445 tkinter how to get