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

Tkinter多用户托管程序按钮状态跨用户实时同步解决方案求助

Solution for Real-Time Button State Sync Across Multiple Tkinter Instances

Great question! The core issue here is that your current setup only checks the database state on startup and when the change value button is clicked—other users' instances have no way to automatically know when the database state changes. Let's fix this step by step:

First, Fix the Button Assignment Bug

Your current code has a critical issue: when you do button_1 = Button(...).pack(), the variable button_1 gets assigned the return value of pack() (which is None), not the actual Button widget. Later redefining button_1 creates a new Button but doesn't display it. Let's correct this:

# Create buttons first, then pack them separately
button_1 = Button(frame1, text="Color change")
button_1.pack()

button_2 = Button(frame2, text="Generate text")
button_2.pack()

button_3 = Button(frame3, text="change value", command=changevalue)
button_3.pack()

Add a Function to Refresh Button State from Database

Create a reusable function that fetches the latest var value from the database and updates the button states. This will be called whenever we need to sync the UI with the database:

def refresh_button_states():
    global var
    # Fetch latest state from database
    c.execute("SELECT var FROM state WHERE id=1")
    var = c.fetchall()[0][0]
    # Update button states
    new_state = 'disabled' if var == 1 else 'normal'
    button_1['state'] = new_state
    button_2['state'] = new_state

Sync State When Tabs Are Changed

Add an event handler for the Notebook tab change event. This way, when any user switches to Mytab1 or Mytab2, the button states will immediately refresh from the database:

def on_tab_change(event):
    refresh_button_states()

# Bind the tab change event
tab.bind("<<NotebookTabChanged>>", on_tab_change)

Add a Periodic Refresh Timer

To ensure state updates are reflected even if the user doesn't switch tabs, add a recurring timer that calls refresh_button_states() at regular intervals (e.g., every 1000ms = 1 second):

def periodic_refresh():
    refresh_button_states()
    # Schedule the next refresh after 1 second
    root.after(1000, periodic_refresh)

# Start the periodic refresh when the app launches
periodic_refresh()

Update the changevalue Function

Simplify the changevalue function to reuse the refresh_button_states() function instead of duplicating logic:

def changevalue():
    # Toggle the value in the database
    c.execute("UPDATE state SET var = 1 - var WHERE id=1")
    conn.commit()
    # Refresh the UI to reflect the new state
    refresh_button_states()

Full Modified Code

Putting it all together, here's the complete working code:

from tkinter import *
import tkinter as tk
from tkinter import ttk
from tkinter.ttk import *
import sqlite3

root = Tk()
conn = sqlite3.connect('/database')
c = conn.cursor()

# Ensure the state table exists (add this if not already created)
c.execute("CREATE TABLE IF NOT EXISTS state (id INTEGER PRIMARY KEY, var INTEGER)")
# Initialize the state if it doesn't exist
c.execute("INSERT OR IGNORE INTO state (id, var) VALUES (1, 0)")
conn.commit()

tab = ttk.Notebook(root)
tab.pack(expand=True, fill=tk.BOTH)

def refresh_button_states():
    global var
    c.execute("SELECT var FROM state WHERE id=1")
    var = c.fetchall()[0][0]
    new_state = 'disabled' if var == 1 else 'normal'
    button_1['state'] = new_state
    button_2['state'] = new_state

def changevalue():
    c.execute("UPDATE state SET var = 1 - var WHERE id=1")
    conn.commit()
    refresh_button_states()

def on_tab_change(event):
    refresh_button_states()

def periodic_refresh():
    refresh_button_states()
    root.after(1000, periodic_refresh)

# Create Frames for tabs
frame1 = ttk.Frame(tab)
frame1.pack(fill="both")
frame2 = ttk.Frame(tab)
frame2.pack(fill="both")
frame3 = ttk.Frame(tab)
frame3.pack(fill="both")

# Add frames to notebook
tab.add(frame1, text='Mytab1')
tab.add(frame2, text='Mytab2')
tab.add(frame3, text='Mytab3')

# Create buttons correctly
button_1 = Button(frame1, text="Color change")
button_1.pack()

button_2 = Button(frame2, text="Generate text")
button_2.pack()

button_3 = Button(frame3, text="change value", command=changevalue)
button_3.pack()

# Bind tab change event
tab.bind("<<NotebookTabChanged>>", on_tab_change)

# Initial state refresh and start periodic updates
refresh_button_states()
periodic_refresh()

root.mainloop()

How This Works

  • Tab Change Sync: When any user switches tabs, the app immediately pulls the latest state from the database and updates the buttons.
  • Periodic Refresh: Even if the user stays on a single tab, the app checks the database every second to pick up changes made by other users.
  • Reusable Logic: The refresh_button_states() function ensures we don't duplicate code when updating states.

Now, when User A clicks "change value", their local UI updates immediately, and any other user will see the button state update either when they switch tabs or within 1 second (thanks to the periodic refresh). No restarts required!

内容的提问来源于stack exchange,提问作者Béa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 08:52:50