IntVar().trace() 不工作

IntVar().trace() not working

我刚开始在 Python/Tkinter 中编写一个小型 Pymol 插件。在这里,我试图有一个切换按钮并在单击时报告其状态。按钮上下移动,但 toggleAVA 永远不会被调用。有什么想法吗?

from Tkinter import *
import tkMessageBox

class AVAGnome:

    def __init__(self, master):
        # create frames
        self.F1 = Frame(rootGnome, padx=5, pady=5, bg='red')

        # checkbuttons
        self.AVAselected = IntVar()
        self.AVAselected.trace("w", self.toggleAVA)
        self.AVAbutton = Checkbutton(self.F1, text='AVA', indicatoron=0, variable=self.AVAselected)

        # start layout procedure
        self.layout()

    def layout(self):
        self.F1.pack(side=TOP, fill=BOTH, anchor=NW)

        #entry and buttons
        self.AVAbutton.pack(side=LEFT)

    def toggleAVA(self, *args):
        if (self.AVAselected.get()):
          avastatus = "selected"
        else:
          avastatus = "unselected"
        tkMessageBox.showinfo("AVA status", avastatus)

def __init__(self):
    open_GnomeUI()

def open_GnomeUI():
    # initialize window
    global rootGnome
    rootGnome = Tk()
    rootGnome.title('AVAGnome')
    global gnomeUI
    gnomeUI = AVAGnome(rootGnome)

我在下面附上了您代码的工作版本。您可以参考它以了解您哪里出错了。通常,如果您使用 class format.This,您必须注意如何构建代码,这将帮助您可视化代码并更好地调试。您可以阅读此 discussion 来帮助您。

from Tkinter import *
import tkMessageBox

class AVAGnome(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)

        # create frames
        self.F1 = Frame(self, padx=5, pady=5, bg='red')

        # checkbutton 
        self.AVAselected = IntVar() 
        self.AVAselected.trace("w", self.toggleAVA)
        self.AVAbutton = Checkbutton(
            self.F1, text='AVA', indicatoron=0, width=10,
            variable=self.AVAselected)

        # start layout procedure
        self.F1.pack(side=TOP, fill=BOTH, anchor=NW)
        self.AVAbutton.pack(side=LEFT) #entry and buttons

    def toggleAVA(self, *args):
        if (self.AVAselected.get()):
          avastatus = "selected"
        else:
          avastatus = "unselected"
        tkMessageBox.showinfo("AVA status", avastatus)

if __name__ == '__main__':
    rootGnome = Tk()
    rootGnome.title('AVAGnome')
    gnomeUI = AVAGnome(rootGnome)
    gnomeUI.pack(fill="both", expand=True)
    gnomeUI.mainloop()

更新: 以上代码结构适用于独立的 tkinter 程序。我正在尝试将此工作代码转换为遵循 Pymol 插件示例。修改后的代码发布在下面,并且可以进一步修改。

# https://pymolwiki.org/index.php/Plugins_Tutorial
# I adapted from the example in the above link and converted my previous code to
# 
from Tkinter import *
import tkMessageBox

def __init__(self): # The example had a self term here.
    self.open_GnomeUI()


class AVAGnome(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)

        # create frames
        self.F1 = Frame(self, padx=5, pady=5, bg='red')

        # checkbutton 
        self.AVAselected = IntVar() 
        self.AVAselected.trace("w", self.toggleAVA)
        self.AVAbutton = Checkbutton(
            self.F1, text='AVA', indicatoron=0, width=10,
            variable=self.AVAselected)

        # start layout procedure
        self.F1.pack(side=TOP, fill=BOTH, anchor=NW)
        self.AVAbutton.pack(side=LEFT) #entry and buttons

    def toggleAVA(self, *args):
        if (self.AVAselected.get()):
          avastatus = "selected"
        else:
          avastatus = "unselected"
        tkMessageBox.showinfo("AVA status", avastatus)

# Note, I added a "self" term throughout function. 
# Try w/ & w/o "self" to see which works. 
def open_GnomeUI(self): 
    self.rootGnome = Tk()
    self.rootGnome.title('AVAGnome')
    self.gnomeUI = AVAGnome(self.rootGnome)
    self.gnomeUI.pack(fill="both", expand=True)
    self.gnomeUI.mainloop()

我用 Pymol 测试了你的代码。

问题是因为您使用 Tk() 创建了 window。您必须使用 Toplevel() 然后它将与 trace()command=.

一起正常工作

Pymol 是用 tkinter 创建的,它只能有一个 window 用 Tk() 创建的 - 它是程序中的主要 window。每隔 window 必须使用 Toplevel() 创建。