python - Tkinter pages updated from separate files
问题描述
Using the below code originally posted here how can i use a 4th module with the PageList()
command and a new page class below it to display it in my WindowHandler()
class? through other research i believe you would have to stop using Windowhandler()
as an instance of the main application class.
The goal of this is to have the stacked frames in different files while each file can update the frames={}
list without any having to add it in the main class. a similar example is given here for different pages but the call to those pages must still be added within the main class.
Nav.py
import tkinter as tk
from Page import PageList
import Mypages
class Windowhandler(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand= True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
PageList("Page1", container, self, Mypages.PageOne)
PageList("Page2", container, self, Mypages.PageTwo)
self.show_frame("Page1")
def show_frame(self, cont):
frameref = PageList.frames[cont]
print(frameref)
frameref.tkraise()
app = Windowhandler()
app.mainloop()
Page.py
class PageList():
frames = {}
def __init__(self, name, parent, cont, ref):
self.frames[name] = ref(parent=parent, controller=cont)
Mypages.py
import tkinter as tk
class PageOne(tk.Frame):
def __init__(self, parent, controller):
this = tk.Frame.__init__(self, parent)
label = tk.Label(this, text="Welcome to Page 1")
label.pack(pady=10, padx=10)
button1 = tk.Button(this, text="Back to Home",
command=lambda: controller.show_frame("Page2"))
button1.pack()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
this = tk.Frame.__init__(self, parent)
label = tk.Label(this, text="Welcome to Page 2")
label.pack(pady=10, padx=10)
button1 = tk.Button(this, text="Back to Home",
command=lambda: controller.show_frame("NewPage"))
button1.pack()
Psuedo.py
import tkinter as tk
import Nav
PageList("NewPage", Nav.container, WindowHandler, NewPage)
class NewPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
btn1 = Nav(self, text="A Button" command=lambda: Controller.show_frame("Page1"))
btn1.pack(pady=(10, 4))
解决方案
下面的代码是我针对上述问题设法提出的,每个帧都存储在子文件夹中的不同文件中,尽管它是使用 importlib 加载的,因为这是我的应用程序所需要的。
addnav
这是通过在 Main.py 文件调用的每个文件中Dstore()
都有一个通用函数来实现的关于子文件。
主文件
from os import listdir
from importlib import import_module
from Resource import *
# Create our main window under the Windowhandler class.
class Windowhandler(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.title(self, "Stacked frames + Stacked window with dynamic imports")
tk.Tk.geometry(self, "800x800")
tk.Tk.state(self, "zoomed")
# Used for displaying stacked frames from frames list in Resource.py
def show_frame(self, cont):
frame = Addnav.frames[cont]
frame.tkraise()
# Find all modules inside module subfolder, import and return list of references.
def importscript(**kwargs):
kwargs["pdir"] = kwargs.get("pdir", "/Users/Main/PycharmProjects/Plugin-Stacked-Frames/Modules")
pdir = kwargs["pdir"]
mlist = {}
for fi, file in enumerate(listdir(pdir)):
if file.endswith(".py") and file != "__init__.py":
module = import_module("Modules." + file.strip(".py"))
module.Dstore()
notify = module.Dstore.Info
print("Imported " + notify["name"])
mlist[fi] = module
return mlist
# This is our root menu that has a button for each sub menu of our sub files.
class MenuHome(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, bg="white")
tk.Label(self, text="Root Menu").pack(pady=(20, 5))
# Enumerate through frames and add a button object referenced to each sub files menu.
for idx, fref in enumerate(Addnav.frames):
sinfo = sub[idx].Dstore.Info
btn = tk.Button(self, text=sinfo["name"], command=lambda fref=fref: controller.show_frame(fref))
btn.pack()
sub = importscript()
app = Windowhandler()
# Create 2 containers 1 for the menu 1 for the main workspace.
container = tk.Frame(app)
container.pack(side="left", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
for N in sub:
pref = sub[N].Dstore.Info
sub[N].addnav(pref["reference"], container, app)
Addnav("MenuHome", container, app, MenuHome)
Windowhandler.show_frame(container, "MenuHome")
app.mainloop()
Subfile1.py(放置在名为 Modules 的子文件夹中)
from Resource import *
# For getting information about the individual subfile.
class Dstore():
Info = {}
def __init__(self):
self.Info["reference"] = "Menu1"
self.Info["name"] = "Sub Menu 1"
# Calls the shared resource Addnav function to add the menu.
def addnav(name, container, app):
Addnav(name, container, app, Menu1)
# The menu class for this file.
class Menu1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, bg="blue")
tk.Label(self, text="Welcome to subfile menu 1").pack(pady=(20, 5))
btn1 = tk.Button(self, text="Home", command=lambda: controller.show_frame("MenuHome"))
btn1.pack()
btn2 = tk.Button(self, text="Subfile menu 2", command=lambda: controller.show_frame("Menu2"))
btn2.pack()
Subfile2.py(放置在名为 Modules 的子文件夹中)
from Resource import *
# For getting information about the individual subfile.
class Dstore():
Info = {}
def __init__(self):
self.Info["reference"] = "Menu2"
self.Info["name"] = "Sub Menu 2"
# Calls the shared resource Addnav function to add the menu.
def addnav(name, container, app):
Addnav(name, container, app, Menu1)
# The menu class for this file.
class Menu1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, bg="red")
tk.Label(self, text="Welcome to subfile 2 menu").pack(pady=(20, 5))
btn1 = tk.Button(self, text="Home", command=lambda: controller.show_frame("MenuHome"))
btn1.pack()
btn2 = tk.Button(self, text="Subfile Menu 1", command=lambda: controller.show_frame("Menu1"))
btn2.pack()
资源.py
import tkinter as tk
class Addnav:
frames = {}
def __init__(self, name, parent, cont, ref):
self.frames[name] = ref(parent=parent, controller=cont)
self.frames[name].grid(row=0, column=0, sticky="nsew")
用于使视觉明显的颜色,请注意我不是 python 大师,在这个其他功能代码中可能有十几个或更多错误,请评论编辑。
推荐阅读
- javascript - 如何从 html 表中的动态生成的输入文件控件中删除一个选定文件的文件
- javascript - 在jQuery中单击自身内部的元素时删除动态生成的元素?
- docker - 如何跟踪是否从我的浏览器/docker 容器发送了 Xdebug 请求?
- android - 使用 MVP 模式从数据库 onClick 中删除 ListView 项
- fonts - 为初始和新框架设置默认 emacs 字体
- windows - 为什么 docker-compose 以一种语法而不是另一种语法创建源目录?
- java - 我在发布模式下运行我的 Flutter 应用程序时遇到问题 - android
- java - 从另一个 dockerized java 应用程序调用 dockerized python 脚本?
- firebase - 尝试使用 API 密钥使应用程序安全,但未使用
- ios - 如何构建适用于 iOS 和 macOS 的混合包?