我试着像这样放置小部件:
我不明白为什么我的代码没有这样做,试图在线查找示例但是没有找到解决方案,我尝试的任何内容都没有让我更接近所要求的结果。
这是我的代码到目前为止(如果您对代码中的任何内容有任何意见,请随时告诉我,因为它是我第一次尝试使用tkinter和GUI):
from Tkinter import *
class box(object):
def __init__ (self, colour,s):
self.root = root
self.listbox = Listbox(self.root, fg = colour, bg = 'black')
self.s = s
self.place_scrollbar()
self.listbox.pack(side = self.s)
def place_scrollbar(self):
scrollbar = Scrollbar(self.root)
scrollbar.pack(side = self.s, fill = Y)
self.listbox.config(yscrollcommand = scrollbar.set)
scrollbar.config(command = self.listbox.yview)
def write(self, contenet):
self.listbox.insert(END, contenet)
root = Tk()
root.resizable(False, False)
boxs = Frame(root)
boxs.pack()
box.root = boxs
server = box("red", LEFT)
client = box("green", RIGHT )
bf = Frame(root)
bf.pack(side = BOTTOM)
entry = Entry(bf,bg ='black', fg = 'white')
entry.pack()
root.mainloop()
答案 0 :(得分:2)
您can't do this在使用pack
的情况下不使用其他框架来包含box
个对象,同时仍保持可恢复性。
但在某些情况下,它更有条理:使用其他框架来包含box
个对象,方法是使用父选项初始化它。
现在box
类中的小部件是全局 root
对象的子元素。这不是一个好习惯。因此,让我们首先通过并使用父对象来用于内部的小部件。
替换:
def __init__ (self, colour,s):
self.root = root
self.listbox = Listbox(self.root, ...)
...
def place_scrollbar(self):
scrollbar = Scrollbar(self.root)
...
使用:
def __init__ (self, parent, colour,s):
self.parent= parent
self.listbox = Listbox(self.parent, ...)
...
def place_scrollbar(self):
scrollbar = Scrollbar(self.parent)
...
这使得您现在需要初始化对象,如下所示:
server = box(root, "red", LEFT)
client = box(root, "green", RIGHT )
现在我们可以传递父窗口小部件,让我们创建一个父框架来包含它们。实际上,已经有一个未使用的框架,boxs
让我们通过将其作为父框架而不是root
来使用它:
server = box(boxs, "red", LEFT)
client = box(boxs, "green", RIGHT )
现在一切看起来都很好,可选择如果您想要使条目占用尽可能多的剩余空间,那么当前将fill='x'
作为选项添加到条目和框架的pack
包含它:
bf.pack(side = BOTTOM, fill='x')
...
entry.pack(fill='x')
您的整个代码应如下所示:
from Tkinter import *
class box(object):
def __init__ (self, parent, colour,s):
self.parent = parent
self.listbox = Listbox(self.parent, fg = colour, bg = 'black')
self.s = s
self.place_scrollbar()
self.listbox.pack(side = self.s)
def place_scrollbar(self):
scrollbar = Scrollbar(self.parent)
scrollbar.pack(side = self.s, fill = Y)
self.listbox.config(yscrollcommand = scrollbar.set)
scrollbar.config(command = self.listbox.yview)
def write(self, contenet):
self.listbox.insert(END, contenet)
root = Tk()
root.resizable(False, False)
boxs = Frame(root)
boxs.pack()
box.root = boxs
server = box(boxs, "red", LEFT)
client = box(boxs, "green", RIGHT )
bf = Frame(root)
bf.pack(side = BOTTOM, fill='x')
entry = Entry(bf,bg ='black', fg = 'white')
entry.pack(fill='x')
root.mainloop()
或:使用grid
代替pack
(columnspan=2
选项进行输入)。
更一般地说,将小部件放在两个并排的小部件之下可以通过以下方式完成:
使用frame
封装并排小部件,然后将frame
放在其他小部件上方:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def main():
root = tk.Tk()
side_by_side_widgets = dict()
the_widget_beneath = tk.Entry(root)
frame = tk.Frame(root)
for name in {"side b", "y side"}:
side_by_side_widgets[name] = tk.Label(frame, text=name)
side_by_side_widgets[name].pack(side='left', expand=True)
frame.pack(fill='x')
the_widget_beneath.pack()
root.mainloop()
if __name__ == '__main__':
main()
使用grid
:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def main():
root = tk.Tk()
side_by_side_widgets = dict()
the_widget_beneath = tk.Entry(root)
for index, value in enumerate({"side b", "y side"}):
side_by_side_widgets[value] = tk.Label(root, text=value)
side_by_side_widgets[value].grid(row=0, column=index)
the_widget_beneath.grid(row=1, column=0, columnspan=2)
root.mainloop()
if __name__ == '__main__':
main()
在不使用其他框架的情况下,通过pack
调用the_widget_beneath
side='bottom'
作为第一个pack
来电,与Bryan's comment中一样:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def main():
root = tk.Tk()
side_by_side_widgets = dict()
the_widget_beneath = tk.Entry(root)
the_widget_beneath.pack(side='bottom')
for name in {"side b", "y side"}:
side_by_side_widgets[name] = tk.Label(root, text=name)
side_by_side_widgets[name].pack(side='left', expand=True)
root.mainloop()
if __name__ == '__main__':
main()
您可以通过创建全局main
方法更轻松地注意全局对象的可靠性,并在其中添加脚本主体并调用:
...
def main():
root = Tk()
root.resizable(False, False)
boxs = Frame(root)
boxs.pack()
box.root = boxs
server = box(boxs, "red", LEFT)
client = box(boxs, "green", RIGHT )
bf = Frame(root)
bf.pack(side = BOTTOM, fill='x')
entry = Entry(bf,bg ='black', fg = 'white')
entry.pack(fill='x')
root.mainloop()
if __name__ == '__main__':
main()
答案 1 :(得分:1)
如何将小部件放在两个使用pack并排的小部件下面?
对于图表中非常简单的布局,您只需先将物品打包在底部。那是因为pack
使用了"腔#34;模型。每个小部件都组织在一个未填充的空腔中。放置该窗口小部件后,腔体的该部分将被填充,并且不可用于任何其他窗口小部件。
在您的情况下,您希望底部空腔填充条目小部件,因此您应该先打包它。然后,在剩余的上腔中,您可以并排放置两个框架,一个在左侧,一个在右侧。
例如:
import Tkinter as tk
root = tk.Tk()
entry = tk.Entry(root)
frame1 = tk.Frame(root, width=100, height=100, background="red")
frame2 = tk.Frame(root, width=100, height=100, background="green")
entry.pack(side="bottom", fill="x")
frame1.pack(side="left", fill="both", expand=True)
frame2.pack(side="right", fill="both", expand=True)
root.mainloop()
在你的问题正文中,事情变得有点复杂,因为你不像你的标题所暗示的那样只有三个小部件,你有几个,有些被打包在根中,有些被打包在其他地方, pack
陈述遍布各处。
使用pack时,最好将小部件分组为垂直或水平切片,而不是在同一组内左右混合顶部/底部。看起来你似乎正试图用你的盒子做这件事,但是你不要 - 你的盒子"实际上是两个小部件。
底线:有条理。如果给定父级的所有pack
(或place
或grid
)语句都在同一代码块中,那么它确实非常有用。当你将它们分散时,就无法实现可视化,也无法修复。此外,请确保窗口小部件具有适当的父窗口。