为什么更改信号会导致正常代码中出现 NameErrors?- PyGtk 问题

为什么更改信号会导致正常代码中出现 NameErrors?- PyGtk 问题

我正在开发一款非常简单的 Ubuntu 应用。我问了一个问题堆栈溢出,而且我遇到的问题似乎是由信号引起的,而不是由变量的范围引起的,正如我最初所想的那样。我遇到的问题是,当TextBox通过整个代码发出信号时activate,它会正常工作。但是当我将信号更改为时,insert-at-click它会在每个非链接函数中返回 NameErrors TextBox。现在,我很可能在这里做错了什么,但信号至少有可能影响全局变量赋值吗?

当前形式的代码给出了 NameErrors:

def on_servername_insertatcursor(self, widget):
global output  
output = StringIO.StringIO()         
servername = widget.get_text()
output.write("USHARE_NAME="+servername+'\n')

def on_netif_changed(self, widget):
netif = widget.get_active_text()
global output
output.write("USHARE_IFACE="+netif+'\n')

def on_port_insertatcursor(self, widget):
global output
port = widget.get_text()
output.write("USHARE_PORT="+port+'\n')

def on_telprt_insertatcursor(self, widget):
global output
telprt = widget.get_text()
output.write("USHARE_TELNET_PORT="+telprt+'\n')

def on_dirs_insertatcursor(self, widget):
global output
dirs = widget.get_text()
output.write("USHARE_DIR="+dirs+'\n')

def on_iconv_toggled(self, widget):
global output
iconv = widget.get_active()
if iconv == True:
    output.write("USHARE_OVERRIDE_ICONV_ERR="+"True"+'\n')
else:
    output.write("USHARE_OVERRIDE_ICONV_ERR="+"False"+'\n')

def on_webif_toggled(self, widget):
global output
webif = widget.get_active()
if webif == True:
    output.write("USHARE_ENABLE_WEB="+"yes"+'\n')
else:
    output.write("USHARE_ENABLE_WEB="+"no"+'\n')

def on_telif_toggled(self, widget):
global output
telif = widget.get_active()
if telif == True:
    output.write("USHARE_ENABLE_TELNET="+"yes"+'\n')
else:
    output.write("USHARE_ENABLE_TELNET="+"no"+'\n')

def on_xbox_toggled(self, widget):
global output
xbox = widget.get_active()
if xbox == True:
    output.write("USHARE_ENABLE_XBOX="+"yes"+'\n')
else:
    output.write("USHARE_ENABLE_XBOX="+"no"+'\n')

def on_dlna_toggled(self, widget):
global output
dlna = widget.get_active()
if dlna == True:
    output.write("USHARE_ENABLE_DLNA="+"yes"+'\n')
else:
    output.write("USHARE_ENABLE_DLNA="+"no"+'\n')

def on_commit_clicked(self, widget):
commit = output.getvalue()
logfile = open('/home/boywithaxe/Desktop/ushare.conf','w')
logfile.write(commit)

def on_endprogram_clicked(self, widget):
sys.exit(0)

答案1

您误解了 Python 中该语句的含义global。以下是 Python 文档的内容:

global 语句 ... 表示列出的标识符将被解释为全局变量。如果没有 global,就不可能分配给全局变量,尽管自由变量可以引用全局变量而无需声明为全局变量。

global blah因此,基本上,只有在需要分配给名为 的全局变量时才需要使用blah。但是,该变量应该已经存在于全局范围内。如果您只是访问全局变量或其方法(与分配给它相反),则无需将其声明为global

所以你需要的是

output = None

def on_servername_insertatcursor(self, widget):
    global output  
    output = StringIO.StringIO()         
    servername = widget.get_text()
    output.write("USHARE_NAME="+servername+'\n')

def on_netif_changed(self, widget):
    netif = widget.get_active_text()
    output.write("USHARE_IFACE="+netif+'\n')

...

但是,使用全局变量并使得整个过程依赖于函数调用的顺序(必须首先调用 on_servername_insertatcursor,否则其他函数将失败)的整个方法并不是一个好的编码实践。

更新:另外,我发现你展示的函数实际上是一个类的方法,对吗?在这种情况下,你可以创建output该类的成员并以如下方式访问它self.output

class MyApp(gtk.Window):

    output = None

    def __init__(...):
        ...
        self.output = StringIO.StringIO()

    def on_servername_insertatcursor(self, widget):    
        servername = widget.get_text()
        self.output.write("USHARE_NAME="+servername+'\n')

    def on_netif_changed(self, widget):
        netif = widget.get_active_text()
        self.output.write("USHARE_IFACE="+netif+'\n')

不过,应用的输出取决于用户点击按钮的顺序,这很不妙。例如,如果用户点击“dlna”复选框两次,配置中将有 2 行,我猜这不是你想要的。

相关内容