侦听器无法识别变量-Jython Swing

时间:2019-03-11 10:20:35

标签: swing awt jython jython-2.7

我正在开发一个简单的窗口,该窗口在关闭时执行一些操作。这是我的代码摘录:

from javax.swing import *
from java.awt import *
from java.awt.event import *
from java.io import *
import javax.swing.table.DefaultTableModel as DefaultTableModel

class registro(JFrame):
   def __init__(self):
      super(registro, self).__init__()
      self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
      self.setExtendedState(JFrame.MAXIMIZED_BOTH)

      #[...]

      headers = ('Data e orario', 
                 'Personale UO Q&A', 
                 'Tipologia di attività'.decode('utf-8'),
                 'Personale incontrato con strutture di appartenenza',
                 'Note')
      self.model = DefaultTableModel([["","","","",""]], headers)
      self.table = JTable(self.model)

      #[...]

      self.addWindowListener(self.onClose())

      #[...]

   def onClose(self):
      class saver(WindowAdapter):
         tableModel = self.model
         def windowClosing(self, event):
            print tableModel #HERE IS THE ERROR!!!!!!!!!
      return saver()

突出显示的行上报告的错误如下:

  

NameError:未定义全局名称'tableModel'

尽管我已在侦听器中声明了变量(以避免在两个 self 之间产生误解),但我不明白为什么从未认识到该变量。我几乎是Jython上面向对象编程和Swing窗口的新手,我希望这不是我的(非常)严重的缺点!

预先非常感谢。

1 个答案:

答案 0 :(得分:1)

这里存在一个相当细微的作用域问题,主要是关于Python语法,也涉及您想要访问tableModel的代码。默认情况下,tableModel变量不可见,因为您位于onClose()函数内部。对此的防御性解决方案是将所需变量显式传递到新的saver对象。我个人更喜欢这样做,因为它可以更明确地声明保护对象的输入。

class WindowAdapter:
    None

class App:
    def __init__(self):
        self.model = 'DUMMYMODEL'

    def onClose(self):
        class Saver(WindowAdapter):
            def __init__(self,tableModel):
                WindowAdapter.__init__(self)
                self.tableModel = tableModel

            def windowClosing(self,event):
                print (self.tableModel)
        return Saver(self.model)


if __name__ == '__main__':
    app = App()
    sv = app.onClose()
    sv.windowClosing(event=None)

(此代码经过了缩减,并在纯Python中显示出它与范围界定在很大程度上相关。)

一种替代方法是使用Python全局关键字将tableModel变量公开给所有较低范围的对象。

class WindowAdapter:
    None

class App:
    def __init__(self):
        self.model = 'DUMMYMODEL'

    def onClose(self):
        global tableModel
        tableModel = self.model

        class Saver(WindowAdapter):
            def windowClosing(self,event):
                print (tableModel)
        return Saver()


if __name__ == '__main__':
    app = App()
    sv = app.onClose()
    sv.windowClosing(event=None)