英文:
Text widget expands wide without being asked to do that (other elements don't expand)
问题
构建一个GUI应用程序,我正在使用Tkinter和ttkbootstrap。
尽管在Tkinter中遇到了各种问题和奇怪/不一致的体验,我成功地构建了一个功能性的GUI应用程序,但我无法正确地为其添加样式,因为Tkinter的行为不稳定。应用程序运行正常,但我的不同对象的配置和参数在随机情况下应用或不应用(但对于每个元素都是固定的 - 可能有一些元素会简单地忽略其他元素不忽略的配置)。我有两个元素的样式完全相同(在放置方面相同的参数,除了网格行),但它们出现不同的屏幕行为,原因不明,我找不到解决方法来让它们按照我的要求执行操作(以及我的当前代码有点建议它们应该执行的操作,但它们没有执行)。
GUI的结构(不是代码)如下:
根窗口。
Labelframe1:根,行=0,列=0,rowspan=1,columnspan=1
Labelframe2:根,行=1,列=0,rowspan=1,columnspan=1
Labelframe3:根,行=2,列=0,rowspan=1,columnspan=1
所有的标签框架都具有相同的样式。 Labelframes
1和2的行为符合预期,第三个执行我从未要求它执行的随机操作。以下是截图:
“日志”标签框架的宽度必须与上面的标签框架相同。它们都占据一个列,并且列跨度为1,它们都占据一行。
无论出于Tkinter的逻辑原因,textbox
的存在都会扩展该列,尽管从未要求这样做。如果我删除文本框(不在其上使用.grid()
),整个界面看起来与预期的一样(请注意列已变窄 - 正是预期的效果):
如果我明确设置Text部件的宽度,它也能按预期工作:
我只想要一个Text小部件,它应该占据根窗口的第一列的整个宽度,就像上面的标签框架一样。但是,Text()
小部件会随机扩展第一列,尽管它是空的,我的代码没有要求这样做:
LogLabelFrame = tb.Labelframe(root, text="Log")
LogLabelFrame.columnconfigure(0, weight=1)
LogLabelFrame.rowconfigure(2, weight=1)
global Logfield
Logfield = tb.Text(LogLabelFrame)
LogSaveButton = tb.Button(LogLabelFrame, text="Save to file...", command=lambda: LogFieldAddLine("Log Test Line"))
LogClearButton = tb.Button(LogLabelFrame, text="Clear Log", command=lambda: LogFieldClear())
LogSaveButton.grid(row=0, column=0, columnspan=1, sticky="news", pady=1)
LogClearButton.grid(row=1, column=0, columnspan=1, sticky="news", pady=1)
Logfield.grid(row=2, column=0, rowspan=1, columnspan=1, sticky="nw")
LogLabelFrame.grid(row=2, column=0, rowspan=1, columnspan=1, padx=(0, 2), sticky="nw")
是否有一种方法可以强制文本小部件占据其父级的整个宽度,但不扩展它?
不幸的是,互联网搜索没有找到任何结果,而且在所有的示例和教程中,所有的样式和布局工具如grid和pack都可以无缺地工作(在我的经验中从未出现这种情况,但这可能是我的无能的问题),我也找不到任何涉及类似问题的材料。
我是否忽略了什么?我是否可以以某种方式强制元素的宽度相对于父元素的宽度为100%?(与HTML/CSS不同,我还没有注意到任何相对大小调整工具)。
英文:
Building a GUI app, and I'm using Tkinter with ttkbootstrap.
Despite all problems and weird/inconsistent experience with Tkinter, I managed to build a functional GUI app, but I can't style it properly, because Tkinter behaves in unstable manner. The app runs ok, but my configurations and parameters for different objects apply or don't apply at random (but fixed for every element - there can be some element that simply ignores the configs that other elements don't ignore). I have literally two elements styled identically (in terms of placement; same params except grid row), but they behave differently on screen for no apparent reason, and I can't find a workaround to make them do what I want them to do (and what my current code kinda suggests they should do, but they don't).
Structure of GUI (not code):
root window.
Labelframe1: root, row=0, column=0, rowspan=1, columnspan=1
Labelframe2: root, row=1, column=0, rowspan=1, columnspan=1
Labelframe3: root, row=2, column=0, rowspan=1, columnspan=1
All of the labelframes are styled identically. Labelframes
1 & 2 behave as expected, the third one does random junk I never asked it to do. Here is the screenshot:
The Log
labelframe must be the same width as those above it. They all take 1 column and have columnspan of 1, they all span 1 row.
ConnectRFFEMasterLabelFrame.grid(row = 0, column = 0, rowspan = 1, columnspan = 1, sticky="nw", padx = (0,2))
ConfigRFFEMasterLabelFrame.grid(row = 1, column = 0, rowspan = 1, columnspan = 1, sticky="nw", padx = (0,2))
LogLabelFrame.grid(row = 2, column = 0, rowspan = 1, columnspan = 1, padx = (0,2), sticky="nw")
For whatever Tkinter logic reason, the presence of textbox
expands the column, even tho it was never asked to do that. If I remove the textbox (don't use .grid()
on it), the whole thing looks exactly as one would expect it to look (notice how the column got narrow - exactly what it is supposed and expected to be):
If I explicitly set the Text widget width, it also works as expected:
All I want to do is to have Text widget that would take full width of the labelframe within the first column of root window, just like labelframes above it do. But the Text()
widget randomly explodes the first column even tho it's empty and none of my code asks for it:
LogLabelFrame = tb.Labelframe(root, text="Log")
LogLabelFrame.columnconfigure(0, weight = 1)
LogLabelFrame.rowconfigure(2, weight = 1)
#LogLabelFrame.columnconfigure(2, weight = 0)
global Logfield
Logfield = tb.Text(LogLabelFrame)
LogSaveButton = tb.Button(LogLabelFrame, text = "Save to file...", command = lambda: LogFieldAddLine("Log Test Line"))
LogClearButton = tb.Button(LogLabelFrame, text = "Clear Log", command = lambda: LogFieldClear())
LogSaveButton.grid(row = 0, column = 0, columnspan = 1, sticky = "news", pady = 1)
LogClearButton.grid(row = 1, column = 0, columnspan = 1, sticky = "news", pady = 1)
Logfield.grid(row = 2, column = 0, rowspan = 1, columnspan = 1, sticky="nw")
LogLabelFrame.grid(row = 2, column = 0, rowspan = 1, columnspan = 1, padx = (0,2), sticky="nw")
Is there a workaround to force text widget to take full width of its parent, but not expand it?
Unfortunately, internet search gave nothing, and in all examples and tutorials all the styling and placement tools like grid and pack work flawlessly (which in my experience was never the case, but that's probably a matter of my incompetence), and I couldn't find any materials which would discuss similar problems.
What am I overlooking? Can I somehow force element to have relative width of 100% of parent? (I haven't noticed any relative sizing tools at all, unlike, say, HTML/CSS)
答案1
得分: 1
有一个解决方法,可以强制文本小部件占据其父元素的全部宽度,但不使其扩展。
解决方案是将大小设置为您认为合适的最小值,然后如果有更多空间,就让它增长。如果不指定大小,那么默认宽度将是80个字符。如果希望小部件开始时较小,请将宽度设置得更小。
由于您正在使用grid
,您还可能需要执行以下操作:
- 使用
sticky="nsew"
来使小部件填充分配给它的所有空间。 - 配置小部件所在的行和列的权重大于零。这将导致额外的空间分配给文本小部件所在的位置。
英文:
> Is there a workaround to force text widget to take full width of its parent, but not expand it?
The solution is to set the size to the smallest value you think is appropriate, and then let it grow if there's more room. If you don't specify a size, the default width is going to be 80 characters. Set the width smaller if you want the widget to start out smaller.
Since you're using grid
, you may need to also do the following:
- you use
sticky="nsew"
to get the widget to fill all space allocated to it - you configure the row and column that the widget is in to have a weight greater than zero. This will cause any extra space to be allocated to the place where the text widget is.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论