如何在pyGTK中正确读取旋转按钮?

0 投票
2 回答
563 浏览
提问于 2025-04-16 06:14

我想为一个小计时器应用程序写一个GTK界面,方便我设置想要的时间。下面是这个界面的图片:

alt text

不过,我在读取旋转按钮的值时遇到了一些问题。我打算按照以下步骤进行:

  1. 通过每个按钮的方法读取它们的值

这是其中一个实现这个功能的方法:

# Get the fields of the spinbuttons
def get_seconds(self, widget, spin):
    self.rSeconds = spin.get_value_as_int()

然后这样调用这个方法:

    button = gtk.Button("Start")
    button.connect("clicked", self.get_seconds, spinnerS)
  1. 用按钮的数据创建一个计时器对象

我计划用这个方法来完成:

    # Create the timer object ...
   def prepare_timer(self, widget, hours, minutes, seconds, title, text):
     self.timer = eggTimer(hours, minutes, seconds, title, text)

这个方法在这里被调用:

button.connect("clicked", self.prepare_timer, self.rHours, self.rMinutes, self.rSeconds, "some title", "some text")

不幸的是,当我运行这个脚本时,出现了以下错误信息:

Traceback (most recent call last):
File "GTKInterface.py", line 140, in <module>
SpinButtonExample()
File "GTKInterface.py", line 126, in __init__
button.connect("clicked", self.prepare_timer, self.rHours, self.rMinutes, self.rSeconds, "Title", "Text")
AttributeError: SpinButtonExample instance has no attribute 'rSeconds'

为了检查这个变量是否真的没有实例,我编写了一个简单的方法来打印它:

   def returnS(self, widget):
       print self.rSeconds

令人惊讶的是,这个方法居然可以“看到”self.rSeconds。这让我想知道,是什么决定了这个变量的可见性。我在读取这个变量时做错了什么呢?

2 个回答

1

根据adw的回答,推荐使用一个点击处理函数,你可以简单地在你的pastebin代码中加上:

def read_and_prepare(self,spinnerS,spinnerM,spinnerH,title,text):
    self.get_seconds(spinnerS)
    self.get_minutes(spinnerM)
    self.get_hours(spinnerH)
    self.prepare_timer(elf.rHours, self.rMinutes, self.rSeconds, title, text)

然后只需要有

button.connect("clicked", self.read_and_prepare,spinnerS,spinnerM,spinnerH,"Title","Text")

用于连接的代码。

你也可以考虑稍微重新设计一下,避免所有的get_*调用,直接在点击处理函数中读取值。

2

你试图把属性 self.rHours 传递给 connect 方法,但在那个时候这个属性还不存在(因为 clicked 处理程序还没有执行)。

注意,即使你在调用 connect 之前就给 self.rHours 赋值,它传递的也是连接时的值,而不是处理程序执行时的值。

你可以通过直接把 self.rHours 等传给 eggTimerprepare_timer 中来解决这个问题。

不过,更简单的方法是把所有的点击处理程序合并成一个,然后使用局部变量,而不是 self.rHours 等。没有必要把代码分散在这么多个点击处理程序里。

编辑: 顺便提一下,你也可以使用嵌套函数来代替方法:

...
def prepare_timer(widget):
    self.timer = eggTimer(
        spinnerH.get_value_as_int(),
        spinnerM.get_value_as_int(),
        spinnerS.get_value_as_int(),
        "Title", "Text")
button.connect("clicked", prepare_timer)
...

保持简单!

撰写回答