You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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="")

解决方案

问题根源在于登录成功后的代码逻辑:

  1. 错误地重新实例化了ttk.Style,覆盖了Home窗口自带的主题配置;
  2. 直接销毁登录窗口可能导致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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 07:24:53