【发布时间】:2020-09-23 04:18:59
【问题描述】:
我为框架定义了 2 个按钮和一个标签,但我看不到它们。 我尝试使用 pack()、grid()、place()。 如果我注释掉框架线,我可以看到容器框架(右框架)上的效果。
大图:
import tkinter as tk
import subprocess as sub
import multiprocessing as mp
import shutil
import time
import io
import os
class GUI(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.geometry("640x478")
self.title("Gil Shwartz GUI Project")
self.resizable(0, 0)
menu = tk.Frame(self, height=250, width=10, relief="solid")
container = tk.Frame(self, relief="flat", height=200, bg="black")
menu.pack(side=tk.LEFT, fill="both", anchor="w")
container.pack(side=tk.TOP, fill="both", expand=True)
menu.grid_rowconfigure(0, weight=1)
self.frames = ["Menu", "MainWelcome", "TestPing", "PageOne", "UptimeCheck"]
self.frames[0] = Menu(parent=menu, controller=self)
self.frames[1] = MainWelcome(parent=container, controller=self)
self.frames[2] = TestPing(parent=container, controller=self)
self.frames[3] = PageOne(parent=container, controller=self)
self.frames[4] = UptimeCheck(parent=container, controller=self)
self.frames[0].grid(row=0, column=0, sticky="nsew")
self.frames[1].grid(row=0, column=0, sticky="nsew")
self.frames[2].grid(row=0, column=0, sticky="nsew")
self.frames[3].grid(row=0, column=0, sticky="nsew")
self.frames[4].grid(row=0, column=0, sticky="nsew")
self.show_frame(1)
def show_frame(self, page_name):
frame = self.frames[page_name]
print(frame)
frame.tkraise()
frame.grid(row=0, column=0, sticky="nsew")
class Menu(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
button1 = tk.Button(self, text="Ping Test", bg="royalblue2",
command=lambda: controller.show_frame(2))
button2 = tk.Button(self, text="Uptime Check", bg="dark violet",
command=lambda: controller.show_frame(4))
buttun3 = tk.Button(self, text="Home", bg="pale goldenrod",
command=lambda : controller.show_frame(1))
button4 = tk.Button(self, text="Quit", bg="gray40",
command=lambda: self.terminate())
button1.pack(fill="both", expand=True)
button2.pack(fill="both", expand=True)
buttun3.pack(fill="both", expand=True)
button4.pack(fill="both", expand=True)
def terminate(self):
path = fr'c:/users/{os.getlogin()}/desktop/Gui-Skeleton'
try:
os.rmdir(path)
except OSError as err:
print(f"Error Deleting tmp folder! {err}")
exit()
class MainWelcome(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
canvas = tk.Canvas(self, bg="black")
canvas.pack(expand=True, fill="both")
class TestPing(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, bg="skyblue1")
self.controller = controller
self.output = tk.LabelFrame(self, text="Output", height=325, width=580, padx=3, pady=3)
self.output.pack(side=tk.BOTTOM, fill="both", expand=True)
self.textbox = tk.Text(self, height=320, width=550, pady=3, padx=3)
self.textbox.pack(side=tk.BOTTOM, fill="both", expand=True)
self.clear_file = tk.BooleanVar()
self.clear_file.set(False)
self.url_label = tk.Label(self, text="Enter URL : ", padx=7, pady=5, bg="skyblue1")
self.url_input_box = tk.Entry(self)
self.url = self.url_input_box.get()
self.url_input_box.grid_columnconfigure(0, weight=0)
self.file_name_label = tk.Label(self, text="Enter Filename: ", bg="skyblue1")
self.file_name_input_box = tk.Entry(self)
self.filename = self.file_name_input_box.get()
self.default_file = fr'c:/users/{os.getlogin()}/desktop/default-tmp.txt'
self.clear_file_label = tk.Label(self, text="Clear File?", padx=5, pady=5, bg="skyblue1")
self.clear_file_radio_yes = tk.Radiobutton(self, text="yes", value=True, var=self.clear_file, bg="skyblue1",
command=lambda: self.callback(self.clear_file.get()))
self.clear_file_radio_no = tk.Radiobutton(self, text="no", value=False, var=self.clear_file, bg="skyblue1",
command=lambda: self.callback(self.clear_file.get()))
self.submit_button = tk.Button(self, text="Submit", width=10, height=1,
command=lambda: self.condition(self.url_input_box.get(),
self.clear_file.get(), self.file_name_input_box.get()))
self.clear_fields_button = tk.Button(self, text="Clear Fields", width=10,
command=lambda: self.clear_boxes(self.url_input_box, self.file_name_input_box))
self.url_label.pack(anchor="w")
self.url_input_box.pack(anchor="w", padx=10)
self.file_name_label.pack(anchor="w", padx=7, pady=5)
self.file_name_input_box.pack(anchor="w", padx=10)
self.clear_file_label.pack(anchor="w")
self.clear_file_radio_yes.pack(anchor="w")
self.clear_file_radio_no.pack(anchor="w")
self.submit_button.pack(anchor="w", pady=1)
self.clear_fields_button.pack(anchor="w")
@classmethod
def clear_boxes(self, urlInputBox, fileNameInputBox):
urlInputBox.delete(0, "end")
fileNameInputBox.delete(0, "end")
@classmethod
def callback(self, clearFile):
print(f'Clear file = {clearFile}') # Debugging Mode - check Radio box Var.
def condition(self, host, clearFile, filenameInputBox):
print(clearFile, filenameInputBox) # Debugging - Input Validation
if clearFile is True and filenameInputBox == '':
self.handler_clr_yes_fn_no(host)
elif clearFile is False and filenameInputBox == '':
self.handler_clr_no_fn_no(host)
elif clearFile is True and filenameInputBox != '':
self.handler_clr_yes_fn_yes(host, filenameInputBox)
elif clearFile is False and filenameInputBox != '':
self.handler_clr_no_fn_yes(host, filenameInputBox)
def handler_clr_yes_fn_no(self, host):
startprocs = []
# nextprocs = []
lastprocs = []
proc1 = mp.Process(name="Clear + No Filename + WriteFile",
target=self.clr_yes_fn_no_writefile, args=(host,))
proc2 = mp.Process(name="Clear + No Filename + PrintOutput",
target=self.clr_yes_fn_no_print_output, args=(host,))
# proc3 = mp.Process(name="Clear + No Filename + Generate PrintOutput to GUI",
# target=self.generate_clr_yes_fn_no_print_output_to_gui, args=(host,))
# proc4 = mp.Process(name="Clear + No Filename + PrintOutput to GUI",
# target=self.clr_yes_fn_no_print_output_to_gui, args=(host,))
proc5 = mp.Process(name="Remove first line + Write new default file",
target=self.delete_default_lines)
startprocs.append(proc1)
startprocs.append(proc2)
# startprocs.append(proc3)
# startprocs.append(proc4)
# nextprocs.append(proc1)
lastprocs.append(proc5)
for s in startprocs:
s.start()
for s2 in startprocs:
s2.join()
# for n in nextprocs:
# n.start()
#
# for p in nextprocs:
# p.join()
for l in lastprocs:
l.start()
def handler_clr_no_fn_no(self, host):
procs = []
nextprocs = []
proc1 = mp.Process(name="Append to default file",
target=self.clr_no_fn_no_writefile, args=(host,))
proc2 = mp.Process(name="Print Output", target=self.clr_no_fn_no_printoutput, args=(host,))
procs.append(proc1)
procs.append(proc2)
for proc in procs:
proc.start()
for proc in procs:
proc.join()
for p in nextprocs:
p.start()
def handler_clr_yes_fn_yes(self, host, filenameInputBox):
procs = []
nextprocs = []
proc1 = mp.Process(name="Clear file + userFilename + Write to file",
target=self.clr_yes_fn_yes_writefile, args=(host, filenameInputBox,))
proc2 = mp.Process(name="Clear file + user filename + Print output",
target=self.clr_yes_fn_yes_printoutput, args=(host,))
proc3 = mp.Process(name="Remove Empty Lines from user filename",
target=self.delete_userfile_lines, args=(filenameInputBox,))
procs.append(proc1)
procs.append(proc2)
nextprocs.append(proc3)
for proc in procs:
proc.start()
for p in procs:
p.join()
for np in nextprocs:
np.start()
def handler_clr_no_fn_yes(self, host, filenameInputBox):
procs = []
proc1 = mp.Process(name="Keep File + Userfilename + Append to Userfile",
target=self.clr_no_fn_yes_writefile, args=(host, filenameInputBox,))
proc2 = mp.Process(name="Keep File + Userfilename + Print Output",
target=self.clr_no_fn_yes_printoutput, args=(host,))
procs.append(proc1)
procs.append(proc2)
for p in procs:
p.start()
for p2 in procs:
p2.join()
@classmethod
def delete_default_lines(cls):
time.sleep(1.5)
print(f'Current Proccess: {mp.current_process().name} + {mp.current_process().pid}')
file = fr'c:/users/{os.getlogin()}/Desktop/Gui-Skeleton/default-tmp.txt'
newfile = fr'c:/users/{os.getlogin()}/Desktop/default.txt'
with open(file, 'r') as inp, open(newfile, 'w+') as out:
for line in inp:
if not line.isspace():
out.write(line.lstrip())
out.write('')
inp.close()
out.close()
os.remove(file)
@classmethod
def delete_userfile_lines(cls, filename):
time.sleep(1.5)
print(f'Current Proccess: {mp.current_process().name} + {mp.current_process().pid}')
file = fr'c:/users/{os.getlogin()}/Desktop/Gui-Skeleton/{filename}-tmp.txt'
newfile = fr'c:/users/{os.getlogin()}/Desktop/{filename}.txt'
with open(file, 'r+') as inp, open(newfile, 'w+') as out:
for line in inp:
if not line.isspace():
out.write(line.lstrip())
out.write('')
inp.close()
out.close()
os.remove(file)
@classmethod
def clr_yes_fn_no_print_output(self, host):
print(f'Current Proccess: {mp.current_process().name} + {mp.current_process().pid}\n')
with sub.Popen(["ping", "-n", "4", f'{host}'], stdout=sub.PIPE,
bufsize=1, universal_newlines=True, stderr=sub.STDOUT) as p:
for line in p.stdout:
print(line, end=' ')
@classmethod
def generate_clr_yes_fn_no_print_output_to_gui(self, host):
print(f'Current Proccess: {mp.current_process().name} + {mp.current_process().pid}\n')
sub.run(f"ping {host}", shell=True, capture_output=True)
@classmethod
def clr_yes_fn_no_print_output_to_gui(self):
tk.Frame.__init__(self, parent)
self.textbox.insert(tk.END, proc.stdout.decode())
@classmethod
def clr_yes_fn_no_writefile(self, host):
print(f'Current Proccess: {mp.current_process().name} + {mp.current_process().pid}\n')
file = fr'c:/users/{os.getlogin()}/Desktop/Gui-Skeleton/default-tmp.txt'
ping = sub.Popen(["ping", "-n", '4', f'{host}'], stdout=sub.PIPE)
with open(file, 'w+') as output:
data = output.read()
for line in ping.stdout.readlines():
data += str(line.decode())
ping.stdout.close()
output.seek(0)
output.write(data.lstrip())
@classmethod
def clr_no_fn_no_printoutput(self, host):
print(f'Current Proccess: {mp.current_process().name} + {mp.current_process().pid}\n')
with sub.Popen(["ping", "-n", '4', f'{host}'], stdout=sub.PIPE,
bufsize=1, universal_newlines=True, stderr=sub.STDOUT) as p:
for line in p.stdout:
print(line, end=' ')
@classmethod
def clr_no_fn_no_writefile(self, host):
print(f'Current Proccess: {mp.current_process().name} + {mp.current_process().pid}')
with open(fr'c:/users/{os.getlogin()}/Desktop/default.txt', 'a') as output:
sub.call(["ping", "-n", '4', f'{host}'], stdout=output)
@classmethod
def clr_yes_fn_yes_printoutput(self, host):
with sub.Popen(["ping", "-n", '4', f'{host}'], stdout=sub.PIPE,
bufsize=1, universal_newlines=True, stderr=sub.STDOUT) as p:
for line in p.stdout:
print(line, end=' ')
@classmethod
def clr_yes_fn_yes_writefile(self, host, filename):
file = fr'c:/users/{os.getlogin()}/Desktop/Gui-Skeleton/{filename}-tmp.txt'
with open(file, 'w') as output:
sub.call(["ping", "-n", '4', f'{host}'], stdout=output)
@classmethod
def clr_no_fn_yes_printoutput(self, host):
with sub.Popen(["ping", "-n", '4', f'{host}'], stdout=sub.PIPE,
bufsize=1, universal_newlines=True, stderr=sub.STDOUT) as p:
for line in p.stdout:
print(line, end=' ')
@classmethod
def clr_no_fn_yes_writefile(self, host, filename):
with open(fr'c:/users/{os.getlogin()}/Desktop/{filename}.txt', 'a') as output:
sub.call(["ping", "-n", '4', f'{host}'], stdout=output)
class UptimeCheck(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
frame = tk.LabelFrame(self, text="Uptime Check", bg="honeydew3", relief="flat")
frame.pack(fill="both", expand=True)
win7_label = tk.Label(self, text="Choose OS", padx=3)
win7_label.pack()
win7_button = tk.Button(self, text="Windows 7")
win10_button = tk.Button(self, text="Windows 10")
win7_button.pack(side=tk.TOP, anchor="n")
win10_button.pack(side=tk.TOP, anchor="n")
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 1", bg="red")
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to page 2",
command=lambda: controller.show_frame(2))
button.pack()
if __name__ == "__main__":
path = fr'c:/users/{os.getlogin()}/desktop/Gui-Skeleton'
try:
os.mkdir(path)
except OSError as err:
print(f"[!] Operation failed! {err}")
app = GUI()
app.mainloop()
正常运行时间类:
class UptimeCheck(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
frame = tk.LabelFrame(self, text="Uptime Check", bg="honeydew3", relief="flat")
frame.pack(fill="both", expand=True)
win7_label = tk.Label(self, text="Choose OS", padx=3)
win7_label.pack()
win7_button = tk.Button(self, text="Windows 7")
win10_button = tk.Button(self, text="Windows 10")
win7_button.pack(side=tk.TOP, anchor="n")
win10_button.pack(side=tk.TOP, anchor="n")
.................................................. ..................................................... ..................................................... ..................................................... ..................................................... ..................................................... .....................
【问题讨论】:
-
那是很多代码。您能否确定您在使用哪些按钮时遇到问题。
-
我将特定类粘贴在主代码下方。除了框架我什么都看不到。
-
想不通。但似乎带有文本“正常运行时间检查”的 LabelFrame 比父级大......,在我看来,包装在 LabelFrame 中的小部件在那里,但由于某种原因你看不到它们。如果我在根窗口中单独运行 UptimeCheck() 类,它就可以工作。
-
在
GUI.__init__()中添加container.rowconfigure(0, weight=1)和container.columnconfigure(0, weight=1)。 -
@acw1668 - 准点!你为什么不把它作为答案?
标签: python-3.x user-interface tkinter tkinter-layout