TkInter的帧让我发疯。我的目标是要有一个选项框,在其中可以选择一些选项,然后按“存档”,然后TkInter窗口将更改为显示脚本其余部分的输出。
我无法正确调整其大小-窗口中似乎还有一些额外的框架占用了空间。
import string
from tkinter import *
import tkinter as tk
import threading
def main(argv):
print("In Main")
for arg in argv:
print(arg)
class TextOut(tk.Text):
def write(self, s):
self.insert(tk.CURRENT, s)
self.see(tk.END)
def flush(self):
pass
class Mainframe(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self._frame = OptionsFrame(self)
self._frame.pack(expand=True)
def change(self, frameClass):
# make new frame - for archive output
self._frame = frameClass(self)
self._frame.pack(fill="both", expand=True)
return self._frame
class Mainframe(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self._frame = OptionsFrame(self)
self._frame.pack(expand=True)
def change(self, newFrameClass):
# make new frame - for archive output
self._frame = newFrameClass(self)
self._frame.pack(fill="both", expand=True)
return self._frame
class OptionsFrame(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
master.title("Test")
master.geometry("325x180")
self.selectedProject = None
self.initUI(master)
def initUI(self, master):
frame1 = Frame(master)
frame1.pack(fill=BOTH, expand=True)
self.label1 = Label(frame1, text="Select Project to Archive, then click Archive")
self.projectListbox = tk.Listbox(frame1, width=60, height=100)
self.projectListbox.bind("<<ProjectSelected>>", self.changeProject)
# create a vertical scrollbar for the listbox to the right of the listbox
self.yscroll = tk.Scrollbar(self.projectListbox,command=self.projectListbox.yview,orient=tk.VERTICAL)
self.projectListbox.configure(yscrollcommand=self.yscroll.set)
# Archive button
self.archiveBtn=tk.Button(frame1,text="Archive",command=self.ArchiveButtonClick)
# Do layout
self.label1.pack()
self.projectListbox.pack(fill="both", expand=True)
self.yscroll.pack(side="right", fill="y")
self.archiveBtn.pack(side="bottom", pady=10, expand=False)
choices = ["test 1", "test 2", "test 3", "test 4", "test 5", "test 6"]
# load listbox with sorted data
for item in choices:
self.projectListbox.insert(tk.END, item)
def getSelectedProject(self):
# get selected line index
index = self.projectListbox.curselection()[0]
# get the line's text
return self.projectListbox.get(index)
# on change dropdown value
def changeProject(self,*args):
self.selectedProject = self.getSelectedProject()
def ArchiveButtonClick(self):
# Switch to second frame - for running the archive
self.changeProject(None)
# Hide existing controls
self.label1.pack_forget()
self.projectListbox.pack_forget()
self.yscroll.pack_forget()
self.archiveBtn.pack_forget()
newFrame = self.master.change(ArchivingOutputFrame)
newFrame.args = [ "-n", self.selectedProject]
newFrame.start()
# Frame shown while archive task is running
class ArchivingOutputFrame(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
master.title("Test Frame 2")
master.geometry("1000x600")
# Set up for standard output in window
self.var = tk.StringVar(self)
lbl = tk.Label(self, textvariable=self.var)
#lbl.grid(row=0, column=0)
lbl.pack(anchor="nw")
def start(self):
t = threading.Thread(target=self.process)
t.start()
def process(self):
main(self.args)
if __name__=="__main__":
# If command line options passed - skip the UI
if len(sys.argv) > 1:
main(sys.argv[1:])
else:
app=Mainframe()
text = TextOut(app)
sys.stdout = text
sys.stderr = text
text.pack(expand=True, fill=tk.BOTH)
app.mainloop()
这是我在用户界面中得到的;请注意,这显示了Microsoft Spy ++的UI层次结构-在窗口的底部有一个我没有创建的框架(至少我不认为我做了),它占据了UI区域的一半;这是黄色的亮点。我的选项窗格因此被压缩到上半部分。
调整大小也不起作用-如果我调整窗口大小,则会得到以下提示:
当我单击按钮和代码以删除选项框架并将其放入从主脚本运行中捕获stdout / stderr的框架时,我得到以下信息:
现在,多余的空间似乎在顶部!
感谢任何想法-我知道我可以切换到使用“网格” UI布局引擎,但这似乎很简单-我没有在这里做任何不适用于pack的复杂工作。
答案 0 :(得分:1)
那是很多复杂的代码。如果提供Minimal, Complete, and Verifiable example,调试起来会更容易。
但是;底部的Frame是在Mainframe()之后打包的TextOut()小部件:
if __name__=="__main__":
app = Mainframe()
text = TextOut(app) # This one
sys.stdout = text
sys.stderr = text
text.pack(expand=True, fill=tk.BOTH)
app.mainloop()
如果为每个小部件赋予bg颜色,然后为它们提供全部填充,则调试起来会更容易,这样您就可以更轻松地识别哪个小部件位于哪个小部件内。