2017-01-24 40 views
0

我剛開始在Python/Tkinter中編寫一個小Pymol插件。在這裏,我試圖設置一個切換按鈕,並在點擊時報告它的狀態。按鈕上下移動,但toggleAVA永遠不會被調用。任何想法爲什麼?IntVar()。trace()不起作用

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) 
+0

'Checkbutton'有選項'command ='所以可以使用'command = self.toggleAVA'而不是'trace()' – furas

+0

是的,但這只是一個非常基本的例子。如果用另一種方式「self.AVAselected」,我可能希望改變狀態。無論如何,我試圖理解爲什麼應該工作的功能不是 – ipetrik

+0

另外,我確實嘗試過(使用'command'),並且'self.AVAselected'的狀態被報告爲'un​​selected',而不管該按鈕是向上或向下。 – ipetrik

回答

1

我用Pymol測試了你的代碼。

問題是因爲您使用Tk()來創建您的窗口。您必須使用Toplevel(),然後才能正確使用trace()command=


Pymoltkinter創建了只能有一個與Tk()創建的窗口 - 它是在程序主窗口。其他窗口必須使用Toplevel()創建。

+0

就是這樣!有趣的是,我試圖通過修復已建立的Pymol插件並用我自己的功能填充它來避免這種情況......顯然,有很多活的髒代碼... – ipetrik

1

我已在下面附上您的代碼的工作版本。你可以參考它來了解你出錯的地方。通常,如果您使用的是類格式,則必須考慮如何構造代碼。這將幫助您更好地形象化代碼並進行調試。你可以閱讀這個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() 
+1

OP不會創建獨立程序,但可能需要不同結構的Pymol插件 - 它可能需要函數'__init__'來運行它(但我不確定) – furas

+0

@furas感謝您指出。我的錯。話雖如此,我已經看過一個Pymol插件示例,並試圖將工作代碼轉換爲遵循該示例。我希望它能起作用。我期望最初有一些接口問題,否則我認爲類部分應該按原樣工作。需要ipetrik才能反饋,如果它工作。在上面發佈修改後的代碼。 –

+0

@孫熊 - 謝謝。目前不能像發佈一樣工作,但它與初始化有關。我會修補並讓它與你提供的課程一起工作並從那裏開始。 – ipetrik