ttkbootstrap跳转窗口后bootstyle失效问题求助
问题描述
使用tkinter和ttkbootstrap开发软件,用户需先完成登录操作,登录成功后跳转至Home窗口。但跳转后Home窗口的bootstyle样式完全失效,单独运行home.py文件时样式显示正常,尝试多种主题应用方式均未解决。
main.py代码
import ttkbootstrap as ttk from orm.window.loginwindow import LoginWindow from orm.home.home import Home from database.internet import have_internet from ttkbootstrap.dialogs import Messagebox if __name__ == "__main__": app = LoginWindow() # app = Home() print(app) app.mainloop()
登录窗口代码
import ttkbootstrap as ttk from ttkbootstrap.constants import * from ttkbootstrap.dialogs import Messagebox from database.auth import login from orm.home.home import Home from database.internet import have_internet import sys, os sys.path.insert(0, os.path.abspath('..')) class LoginWindow(ttk.Window): def __init__(self): super().__init__(themename="superhero") self.title("MidGen (Login)") self.geometry("750x550") # username entry ttk.Label(self, text="Username: ").place(relx=0.3, rely=0.3) self.username = ttk.Entry(self) self.username.configure(bootstyle="success", width=40) self.username.place(relx=0.3, rely=0.35) # password entry ttk.Label(self, text="Password: ").place(relx=0.3, rely=0.45) self.password = ttk.Entry(self) self.password.configure(bootstyle="success", width=40, show="*") self.password.place(relx=0.3, rely=0.50) # show pass or not self.show_or_not = ttk.IntVar() pass_check = ttk.Checkbutton( self, bootstyle="primary", text="Show password", variable=self.show_or_not, onvalue=1, offvalue=0, command=lambda: self.password.configure(show="") if self.show_or_not.get() == 1 else self.password.configure(show="*")) pass_check.place(relx=0.3, rely=0.60) # login button login_btn = ttk.Button(self) login_btn.configure(bootstyle="success", text="Login", width=40, command=self.login) login_btn.place(relx=0.3, rely=0.67) self.resizable(False, False) def login(self): un = self.username.get() ps = self.password.get() if not have_internet(): Messagebox.show_error("Check your internet connection", "Error") return data = login(un, ps) print(data["status"]) if data["status"] == 200: self.destroy() home_view = Home() style = ttk.Style("darkly") home_view.mainloop() else: Messagebox.show_error("Username not found or wrong password\nTry again!", "Error")
Home窗口代码
import ttkbootstrap as ttk from ttkbootstrap.constants import * import tkinter as tk from ..common.menubar import Menubar from ..frames.frames import Dashboard, Map class Home(ttk.Window): def __init__(self): super().__init__(themename="superhero") self.title("MidGen") self.width = self.winfo_screenwidth() self.height = self.winfo_screenheight() self.geometry(f"{self.width}x{self.height}") menubar = Menubar(self) self.config(menu=menubar.menubar) # sidebar self.sidebar = ttk.Frame(self, bootstyle="success") self.sidebar.configure(bootstyle="success") self.sidebar.place(relx=0, rely=0, relwidth=0.2, relheight=1) self.brand_frame = ttk.Frame(self.sidebar, bootstyle="success") self.brand_frame.place(relx=0, rely=0, relwidth=1, relheight=0.15) bname = ttk.Label(self.brand_frame, text="MidGen", bootstyle="inverse-success", font=("", 15, "bold")) bname.place(relx=.5, rely=.1, anchor="center") # sidebar button frame self.options = ttk.Frame(self.sidebar, bootstyle="success") self.options.place(relx=0, rely=0.05, relwidth=1, relheight=.2) # home button self.op1 = ttk.Button(self.options, text="Dashboard", style="TButton", command=self.show_dashboard) self.op1.place(relx=0, rely=0, relwidth=1) self.op1['padding'] = (10, 10) # cursor pointer on hover self.op1.bind("<Enter>", self.on_button_enter) self.op1.bind("<Leave>", self.on_button_leave) # contacts button self.op2 = ttk.Button(self.options, text="Contacts", command=self.show_contacts) self.op2.place(relx=0, rely=.4, relwidth=1) self.op2['padding'] = (10, 10) self.op2.bind("<Enter>", lambda event: self.op2.config(cursor="hand2")) self.op2.bind("<Leave>", lambda event: self.op2.config(cursor="")) # map button self.op3 = ttk.Button(self.options, text="Map", command=lambda: self.map.tkraise()) self.op3.place(relx=0, rely=.8, relwidth=1) self.op3['padding'] = (10, 10) self.op3.bind("<Enter>", lambda event: self.op3.config(cursor="hand2")) self.op3.bind("<Leave>", lambda event: self.op3.config(cursor="")) # dashboard self.dashboard = ttk.Frame(self, bootstyle="danger") self.dashboard.place(relx=.2, rely=0, relwidth=.8, relheight=1) self.maindash = Dashboard(self.dashboard) self.maindash.place(relx=0, rely=0) # contacts self.contacts = ttk.Frame(self, bootstyle="warning") self.contacts.place(relx=.2, rely=0, relwidth=.8, relheight=1) # map self.map = ttk.Frame(self, bootstyle="dark") self.map.place(relx=.2, rely=0, relwidth=.8, relheight=1) self.mainmap = Map(self.map) self.mainmap.place(relx=0, rely=0, relwidth=1, relheight=1) self.dashboard.tkraise() def show_dashboard(self): self.dashboard.tkraise() def show_contacts(self): self.contacts.tkraise() def on_button_enter(self, event): self.op1.config(cursor="hand2") # Change cursor to pointer on hover def on_button_leave(self, event): self.op1.config(cursor="")
解决方案
问题根源在于登录成功后的代码逻辑:
- 错误地重新实例化了
ttk.Style,覆盖了Home窗口自带的主题配置; - 直接销毁登录窗口可能导致ttkbootstrap的样式上下文丢失。
具体修改步骤
1. 修复登录窗口的login方法
删除多余的样式实例化代码,改用隐藏窗口而非直接销毁:
def login(self): un = self.username.get() ps = self.password.get() if not have_internet(): Messagebox.show_error("检查网络连接", "错误") return data = login(un, ps) print(data["status"]) if data["status"] == 200: self.withdraw() # 隐藏登录窗口,保留样式上下文 home_view = Home() home_view.mainloop() self.destroy() # Home窗口关闭后再销毁登录窗口 else: Messagebox.show_error("用户名不存在或密码错误\n请重试!", "错误")
2. 修复Home窗口的按钮样式
将op1按钮的style="TButton"替换为ttkbootstrap的bootstyle,确保样式正确应用:
self.op1 = ttk.Button(self.options, text="Dashboard", bootstyle="success", command=self.show_dashboard)
修改后,跳转至Home窗口时,bootstyle样式就能正常生效,和单独运行home.py的效果一致。
内容的提问来源于stack exchange,提问作者Ashiqul Islam Ayon
相关产品推荐
相关产品推荐

