【问题标题】:make modifications instantly in tkinter在 tkinter 中立即进行修改
【发布时间】:2021-10-29 01:30:37
【问题描述】:

我通过托管系统创建了一个供多个用户使用的程序。

这个程序的目的是当用户A点击按钮改变值时,按钮颜色改变和生成文本立即改变状态(正常到禁用)。 用户 B 在不重新启动程序的情况下单击选项卡 1 时必须看到更改。用户不必重新启动程序即可看到更改。但是在这里,我的代码有效,但用户必须重新启动程序才能看到其他用户所做的更改...... 我不想要那个。有什么解决办法吗?

谢谢

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()

query = "SELECT var FROM state WHERE id=1"
c.execute( query )
var = c.fetchall()[0][0]

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


def changevalue() :
    global var
    query = "SELECT var FROM state WHERE id=1"
    c.execute( query )
    var = c.fetchall()[0][0]

    if var == 1 :
        query = "UPDATE state SET var=0 WHERE id=1"
        conn.execute( query )
        conn.commit()
        button_1['state'] = 'normal'
        button_2['state'] = 'normal'

    if var == 0 :
        query = "UPDATE state SET var=1 WHERE id=1"
        conn.execute( query )
        conn.commit()
        button_1['state'] = 'disabled'
        button_2['state'] = 'disabled'


# create Frames for tab

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

tab.add( frame1, text = 'Mytab1' )
tab.add( frame2, text = 'Mytab2' )
tab.add( frame3, text = 'Mytab3' )

# Button in each tab
button_1 = Button( frame1, text = "Color change" ).pack()
button_2 = Button( frame2, text = "Generate text" ).pack()
button_3 = Button( frame3, text = "change value", command = changevalue ).pack()

if var == 1 :
    button_1 = Button( frame1, text = "Color change", state = 'disabled' )
    button_2 = Button( frame2, text = "Generate text", state = 'disabled' )
else :
    button_1 = Button( frame1, text = "Color change", state = 'normal' )
    button_2 = Button( frame2, text = "Generate text", state = 'normal' )
root.mainloop()

【问题讨论】:

  • 创建一个名为scheduler 的函数,然后在里面说root.after(5000,changevalue)。这将保持每 5 秒运行一次该功能。同时对函数进行初始调用。
  • 请阅读PEP 8。不建议您有那么多空格。
  • 另外你为什么要创建2个button_1s和2个nutton_2s? This 也可能有帮助
  • @TheLizzard 如果您在空格上提到 pep,可能还会提到导入所有内容,尤其是在这种情况下是一个非常可怕的想法。对于 OP:不要从模块中导入所有内容(导入时不要使用 *)它可以,在这种情况下它可能会导致问题,因为两个模块都有一些相似的类名,你也已经 import tkinter as tkfrom tkinter import ttk 所以请相应地使用这些别名,因为大多数代码已经这样做了
  • @Matiiss 大多数人不遵守 don't import * 规则,所以我只是放弃告诉别人。我仍然从不使用 from ... import *,但是有太多人使用它来尝试改变他们的行为。

标签: python sqlite tkinter


【解决方案1】:

由于您已经使用 sqlite3 表在进程间共享状态,因此您应该使用after() 定期检查表并更新按钮的状态。

以下是修改后的代码:

import tkinter as tk
from tkinter import ttk
import sqlite3

conn = sqlite3.connect("/database")
c = conn.cursor()

def get_value():
    c.execute("SELECT var FROM state WHERE id = 1")
    return c.fetchone()[0]

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

def check_value():
    state = 'disabled' if get_value() == 1 else 'normal'
    button_1.config(state=state)
    button_2.config(state=state)
    root.after(100, check_value)

root = tk.Tk()

tab = ttk.Notebook(root)
tab.pack(fill='both', expand=1)

frame1 = ttk.Frame(tab)
frame2 = ttk.Frame(tab)
frame3 = ttk.Frame(tab)

tab.add(frame1, text='Mytab1')
tab.add(frame2, text='Mytab2')
tab.add(frame3, text='Mytab3')

button_1 = ttk.Button(frame1, text='Color change')
button_1.pack()

button_2 = ttk.Button(frame2, text='Generate text')
button_2.pack()

ttk.Button(frame3, text='Change value', command=change_value).pack()

check_value() # check value and update state of buttons periodically
root.mainloop()

注意:

  • 最好避免使用from xxx import *
  • 您无需在这些帧上调用 .pack()
  • 你应该把button_1 = Button(...).pack()分成两行,同样适用于button_2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    相关资源
    最近更新 更多