使用同一类中另一个的值更新一个Pmw控件

时间:2014-07-05 16:29:47

标签: python tkinter

我正在为PyMOL(http://pmw.sourceforge.net)编写一个Pmw(http://sourceforge.net/projects/pymol/)插件,但我无法使用对Pmw.ComboBox所做的更改来更新Pmw.RadioSelect的值控制。

我不断得到的错误是:

    File "/Users/x/.pymol/plugins/mymixer.py", line 82, in sdqRadioChanged
    self.scheme_listing._list.setlist(scList)
<type 'exceptions.AttributeError'>: MyMixer instance has no attribute 'scheme_listing'

这似乎是范围错误,但我不知道如何重新构建整个插件以便能够访问scheme_listing实例的MyMixer属性。在Web上,python / Pmw / tkinter的类似示例似乎工作正常(或者我对python GUI编程的理解有限)。

下面附有一个MWE,它在PyMOL中运行(并失败)(显示在Plugins&gt; MyMixer下的菜单中)。注意:如果在OSX上运行此命令,请确保运行PyMOLX11Hybrid.app

# -*- coding: utf-8 -*-

# ==========================
# IMPORTS
# ==========================

import Pmw

# ==========================
#  MAIN CLASS
# ==========================

class MyMixer():

    colbrew = {'color':{'red': ['apple', 'strawberry', 'carrot'],
                    'blue': ['blueberry', 'smurfberry', 'icee'],
                    'green': ['spinach', 'chilli', 'lettuce']},
               'shape':{'round': ['baseball', 'basketball', 'golfball'],
                    'oblong': ['football', 'shoes', 'eggs'],
                    'square': ['box', 'laptop', 'yourhead']}}

    def __init__(self, app):

        parent = app.root
        self.parent = parent
        self.dialog = Pmw.Dialog(parent, buttons=('Exit', ),
                             title='MyMixer Plugin',
                             command=self.button_pressed)
        self.dialog.geometry('650x780')
        self.dialog.bind('<Return>', self.button_pressed)

        # -- Initialize main notebook
        self.notebook = Pmw.NoteBook(self.dialog.interior())
        self.notebook.pack(fill='both', expand=1, padx=3, pady=3)

        self.sdq_radio = Pmw.RadioSelect(self.dialog.interior(),
                                     selectmode='single',
                                     buttontype='radiobutton',
                                     labelpos='nw',
                                     label_text='Colbrew Style:',
                                     label_font='inconsolata 16',
                                     orient='horizontal',
                                     frame_relief='ridge',
                                     command=self.sdqRadioChanged)

        self.sdq_radio.pack(padx=0, anchor='n')

        schemeStyleTypes = self.colbrew.keys()

        for item in schemeStyleTypes:
            self.sdq_radio.add(item, font='inconsolata 16')

        self.sdq_radio.invoke(0)

        scListItems = self.colbrew.get(self.sdq_radio.getvalue())

        self.scheme_listing = Pmw.ComboBox(self.dialog.interior(),
                                    scrolledlist_items=scListItems,
                                    labelpos='nw',
                                    label_text='Scheme Name:',
                                    label_font='inconsolata 16',
                                    listbox_height=10,
                                    entry_width=3,
                                    selectioncommand=self.schemeListCommand,
                                    dropdown=True)

        self.scheme_listing.pack(padx=20, pady=2, anchor='e')

        # -- Reflow notebook

        self.notebook.setnaturalsize()

        # -- Show the main dialog

        self.dialog.show()

    def schemeListCommand(self, value):
        print value

    def sdqRadioChanged(self, value):
        scList = self.colbrew.get(value)
        self.scheme_listing._list.setlist(scList) # THIS IS THE POINT OF FAILURE !!!
        print value

    # -- Utility function for button controls

    def button_pressed(self, result):
        if result == 'Exit' or result is None:
           self.dialog.withdraw()

# ==========================
#  PLUGIN INITIALIZATION
# ==========================

def __init__(self, *args):
    self.menuBar.addmenuitem('Plugin', 'command', 'Start MyMixer',
                         label='MyMixer',
                         command=lambda s=self: MyMixer(s))

1 个答案:

答案 0 :(得分:0)

您在定义self.sdq_radio.invoke(0)的语句之前调用self.scheme_listing。当您调用invoke方法时,它会在设置之前尝试访问该变量。您应该在调用invoke方法之前设置变量。