2

我刚刚开始使用 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)
4

2 回答 2

4

我用Pymol.

问题是因为你Tk()用来创建你的窗口。您必须使用Toplevel(),然后它才能与trace()或 一起正常工作command=


Pymol创建时tkinter只能创建一个窗口Tk()- 它是程序中的主窗口。每个其他窗口都必须使用Toplevel().

于 2017-01-24T19:26:09.490 回答
1

我在下面附上了您的代码的工作版本。你可以参考它来了解你哪里出错了。一般来说,如果你使用类格式,你必须注意你的代码结构。这将帮助你更好地可视化你的代码和调试。您可以阅读此讨论以帮助您。

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()
于 2017-01-24T07:21:38.117 回答