Tkinter:包含框架的网格包含网格
Tkinter: Grid containing frame containing grid
这稍微暴露了我正在构建的整个程序,但无论如何它只是前端。如果你们想自己制作应用程序,请继续。 :P
所以,正如标题所说,我正在尝试制作一个包含一个框架的网格,该框架包含一个网格,我已经查看了几个类似的问题但没有完全得到答案,可能是因为我我是 guis 和 tkinter 的新手,解决方案通常适合他们的特定程序。所以这是一个适合我的类似问题。
我想做的是用如下所示的整体框架结构构建一些东西:GUI Frame structure,其中除了 ioFrame 之外的每个框架都是一个 2x2 网格。 ioFrame 包含两件事:输入行和输出行。简而言之,这是一个计算逻辑输入的计算器,你的唯一"numbers"是真假。
这是我的 atm 密码:
from tkinter import *;
class calculator:
#def update(self,
def __init__(self, window):
"""
Constructor method.
"""
self.toCompute = []; self.In = StringVar(); self.Out = StringVar();
# Window title
window.title("Logic Calculator");
# The set of 5 frames.
ioFrame = Frame(window, relief=GROOVE, borderwidth=3); ioFrame.grid(row=0); ioFrame.pack();
nwFrame = Frame(window); nwFrame.grid(row=1,column=0); nwFrame.pack();
neFrame = Frame(window); neFrame.grid(row=1,column=1); neFrame.pack();
swFrame = Frame(window); swFrame.grid(row=2,column=0); swFrame.pack();
seFrame = Frame(window); seFrame.grid(row=2,column=1); seFrame.pack();
# Top 2 rows: the IO portion
Label(ioFrame, textvariable=self.In, relief=SUNKEN).grid(row=0, sticky=W);
Label(ioFrame, textvariable=self.Out).grid(row=1, sticky=E);
# Top left 2x2 Frame: [ ( | ) ][ T | F ]
brlButton = Button(nwFrame, text='(', height=2, width=10).grid(row=0,column=0);
brrButton = Button(nwFrame, text=')', height=2, width=10).grid(row=0,column=1);
truButton = Button(nwFrame, text='T', height=2, width=10).grid(row=1,column=0);
falButton = Button(nwFrame, text='F', height=2, width=10).grid(row=1,column=1);
# Top right 2x2 Frame: [ AND | OOR ][ NND | NOR ]
andButton = Button(neFrame, text='and', height=2, width=10).grid(row=0,column=0);
oorButton = Button(neFrame, text='oor', height=2, width=10).grid(row=0,column=1);
nndButton = Button(neFrame, text='nnd', height=2, width=10).grid(row=1,column=0);
norButton = Button(neFrame, text='nor', height=2, width=10).grid(row=1,column=1);
# Bottom left 2x2 Frame: [ SSO | IIF ][ NSO | NIF ]
andButton = Button(swFrame, text='sso', height=2, width=10).grid(row=0,column=0);
oorButton = Button(swFrame, text='iif', height=2, width=10).grid(row=0,column=1);
nndButton = Button(swFrame, text='nso', height=2, width=10).grid(row=1,column=0);
norButton = Button(swFrame, text='nif', height=2, width=10).grid(row=1,column=1);
# Bottom right 2x2 Frame:[ EEQ | NEG ][ NEQ | === ]
eeqButton = Button(seFrame, text='eeq', height=2, width=10).grid(row=0,column=0);
negButton = Button(seFrame, text='neg', height=2, width=10).grid(row=0,column=1);
neqButton = Button(seFrame, text='neq', height=2, width=10).grid(row=1,column=0);
comButton = Button(seFrame, text='=', height=2, width=10).grid(row=1,column=1);
if __name__ == "__main__": # Only runs program if this specfic file is opened.
window = Tk(); # The window
calculator(window);
window.mainloop();
我仍然需要向这些添加命令(我已经在单独的文件中编写了这些命令),但我现在只是想单独完成 gui。
我的问题是我的代码输出的是这个结果:Current GUI。这显然与我的目标相去甚远。作为新手,我可能有一系列问题。
如有任何帮助,我们将不胜感激。
我在这里假设你是从另一种语言来到 python 因为所有的分号。在 python、 中您不需要分号 。如果您 真的 想将这些变量全部放在一行中,我在顶部了解到,但脚本中的每一行不应以分号结尾。
其次,如果您打印出您放入变量中的任何按钮的值,您将看到它是 None
而不是 tkinter.Button
object。这是因为行尾的 .grid(...)
调用 (grid
returns None
)。通常,如果我打算稍后在应用程序中使用它,我只会将小部件放入变量中。如果不是,我会按照您对标签所做的操作,只是在其前面不带 some_variable_name =
的情况下调用它们。如果您稍后尝试对这些按钮变量做任何事情,它将不起作用,因为它们都是 None
.
如评论中所述,我无法将您提供的代码发送至 运行,因为您使用的是 .grid(...)
和 .pack(...)
将框架放在 window 上。你只需要一个。这实际上是导致我出错的原因。将 window 或 Frame 视为容器;如果您使用 grid
将某些东西放入该容器中,则您不能使用 pack
将其他东西放入该容器中。放置小部件的不同方法相互冲突。我相信你得到的输出是因为它会使用 grid
放置框架,然后使用 pack
re-place 它们,这就是它们垂直对齐的原因。
所以考虑到所有这些,这就是我所拥有的:
########## Frames ##########
# this is what the frames should look like in your code
frame = Frame(window, ...)
frame.grid(row=, column=)
########## Buttons ##########
# if you want to keep the buttons in variables
btn = Button(parent, text='', width=, height=)
btn.grid(row=, column=)
# or
# if the buttons don't have to be in variables, like your Labels
Button(parent, text='', width=, height=).grid(row=, column=)
您的按钮变量也有错字。在 Bottom left 2x2 Frame
部分,应更改按钮变量名称以匹配部分标题(如果保留变量名称):
ssoButton = ...
iifButton = ...
nsoButton = ...
nifButton = ...
按钮变量只是对按钮 object 的引用,因此重复使用名称无关紧要,除非您想稍后在代码中使用这些按钮。在那种情况下,它会引起问题,就像我之前说的那样。
我更新了部分代码,您可以看到它应该是什么样子:
编辑:我差点忘了 ioFrame。应该允许扩展以填充顶部提供的 space,但事实并非如此。要解决此问题:
ioFrame = Frame(window, relief=GROOVE, borderwidth=3, bg='green')
ioFrame.grid(row=0, columnspan=2, sticky=N+E+S+W)
我将背景设置为绿色只是为了确保它填充 space,并将 StringVars 设置为一些虚拟文本以进行测试(这样做:self.In.set('text here')
以更改文本)。完成所有更改后,这是我的输出:
这稍微暴露了我正在构建的整个程序,但无论如何它只是前端。如果你们想自己制作应用程序,请继续。 :P
所以,正如标题所说,我正在尝试制作一个包含一个框架的网格,该框架包含一个网格,我已经查看了几个类似的问题但没有完全得到答案,可能是因为我我是 guis 和 tkinter 的新手,解决方案通常适合他们的特定程序。所以这是一个适合我的类似问题。
我想做的是用如下所示的整体框架结构构建一些东西:GUI Frame structure,其中除了 ioFrame 之外的每个框架都是一个 2x2 网格。 ioFrame 包含两件事:输入行和输出行。简而言之,这是一个计算逻辑输入的计算器,你的唯一"numbers"是真假。
这是我的 atm 密码:
from tkinter import *;
class calculator:
#def update(self,
def __init__(self, window):
"""
Constructor method.
"""
self.toCompute = []; self.In = StringVar(); self.Out = StringVar();
# Window title
window.title("Logic Calculator");
# The set of 5 frames.
ioFrame = Frame(window, relief=GROOVE, borderwidth=3); ioFrame.grid(row=0); ioFrame.pack();
nwFrame = Frame(window); nwFrame.grid(row=1,column=0); nwFrame.pack();
neFrame = Frame(window); neFrame.grid(row=1,column=1); neFrame.pack();
swFrame = Frame(window); swFrame.grid(row=2,column=0); swFrame.pack();
seFrame = Frame(window); seFrame.grid(row=2,column=1); seFrame.pack();
# Top 2 rows: the IO portion
Label(ioFrame, textvariable=self.In, relief=SUNKEN).grid(row=0, sticky=W);
Label(ioFrame, textvariable=self.Out).grid(row=1, sticky=E);
# Top left 2x2 Frame: [ ( | ) ][ T | F ]
brlButton = Button(nwFrame, text='(', height=2, width=10).grid(row=0,column=0);
brrButton = Button(nwFrame, text=')', height=2, width=10).grid(row=0,column=1);
truButton = Button(nwFrame, text='T', height=2, width=10).grid(row=1,column=0);
falButton = Button(nwFrame, text='F', height=2, width=10).grid(row=1,column=1);
# Top right 2x2 Frame: [ AND | OOR ][ NND | NOR ]
andButton = Button(neFrame, text='and', height=2, width=10).grid(row=0,column=0);
oorButton = Button(neFrame, text='oor', height=2, width=10).grid(row=0,column=1);
nndButton = Button(neFrame, text='nnd', height=2, width=10).grid(row=1,column=0);
norButton = Button(neFrame, text='nor', height=2, width=10).grid(row=1,column=1);
# Bottom left 2x2 Frame: [ SSO | IIF ][ NSO | NIF ]
andButton = Button(swFrame, text='sso', height=2, width=10).grid(row=0,column=0);
oorButton = Button(swFrame, text='iif', height=2, width=10).grid(row=0,column=1);
nndButton = Button(swFrame, text='nso', height=2, width=10).grid(row=1,column=0);
norButton = Button(swFrame, text='nif', height=2, width=10).grid(row=1,column=1);
# Bottom right 2x2 Frame:[ EEQ | NEG ][ NEQ | === ]
eeqButton = Button(seFrame, text='eeq', height=2, width=10).grid(row=0,column=0);
negButton = Button(seFrame, text='neg', height=2, width=10).grid(row=0,column=1);
neqButton = Button(seFrame, text='neq', height=2, width=10).grid(row=1,column=0);
comButton = Button(seFrame, text='=', height=2, width=10).grid(row=1,column=1);
if __name__ == "__main__": # Only runs program if this specfic file is opened.
window = Tk(); # The window
calculator(window);
window.mainloop();
我仍然需要向这些添加命令(我已经在单独的文件中编写了这些命令),但我现在只是想单独完成 gui。
我的问题是我的代码输出的是这个结果:Current GUI。这显然与我的目标相去甚远。作为新手,我可能有一系列问题。
如有任何帮助,我们将不胜感激。
我在这里假设你是从另一种语言来到 python 因为所有的分号。在 python、 中您不需要分号 。如果您 真的 想将这些变量全部放在一行中,我在顶部了解到,但脚本中的每一行不应以分号结尾。
其次,如果您打印出您放入变量中的任何按钮的值,您将看到它是 None
而不是 tkinter.Button
object。这是因为行尾的 .grid(...)
调用 (grid
returns None
)。通常,如果我打算稍后在应用程序中使用它,我只会将小部件放入变量中。如果不是,我会按照您对标签所做的操作,只是在其前面不带 some_variable_name =
的情况下调用它们。如果您稍后尝试对这些按钮变量做任何事情,它将不起作用,因为它们都是 None
.
如评论中所述,我无法将您提供的代码发送至 运行,因为您使用的是 .grid(...)
和 .pack(...)
将框架放在 window 上。你只需要一个。这实际上是导致我出错的原因。将 window 或 Frame 视为容器;如果您使用 grid
将某些东西放入该容器中,则您不能使用 pack
将其他东西放入该容器中。放置小部件的不同方法相互冲突。我相信你得到的输出是因为它会使用 grid
放置框架,然后使用 pack
re-place 它们,这就是它们垂直对齐的原因。
所以考虑到所有这些,这就是我所拥有的:
########## Frames ##########
# this is what the frames should look like in your code
frame = Frame(window, ...)
frame.grid(row=, column=)
########## Buttons ##########
# if you want to keep the buttons in variables
btn = Button(parent, text='', width=, height=)
btn.grid(row=, column=)
# or
# if the buttons don't have to be in variables, like your Labels
Button(parent, text='', width=, height=).grid(row=, column=)
您的按钮变量也有错字。在 Bottom left 2x2 Frame
部分,应更改按钮变量名称以匹配部分标题(如果保留变量名称):
ssoButton = ...
iifButton = ...
nsoButton = ...
nifButton = ...
按钮变量只是对按钮 object 的引用,因此重复使用名称无关紧要,除非您想稍后在代码中使用这些按钮。在那种情况下,它会引起问题,就像我之前说的那样。
我更新了部分代码,您可以看到它应该是什么样子:
编辑:我差点忘了 ioFrame。应该允许扩展以填充顶部提供的 space,但事实并非如此。要解决此问题:
ioFrame = Frame(window, relief=GROOVE, borderwidth=3, bg='green')
ioFrame.grid(row=0, columnspan=2, sticky=N+E+S+W)
我将背景设置为绿色只是为了确保它填充 space,并将 StringVars 设置为一些虚拟文本以进行测试(这样做:self.In.set('text here')
以更改文本)。完成所有更改后,这是我的输出: