【问题标题】:How to stop infinite recursion when Python objects trigger each other's updates?当 Python 对象触发彼此的更新时,如何停止无限递归?
【发布时间】:2010-12-18 17:29:03
【问题描述】:

我正在使用 PyGTK 和 gtk.Assistant 小部件。在一页上,我有六个组合框,它们最初具有相同的内容(六个数字)。当用户在其中一个组合框中选择一个数字时,该数字不应再在其他五个框中可用(除非它在原始列表中作为副本出现)。因此,我想始终更新内容。

我已经尝试了以下方法(这里只是一些代码 sn-ps),但是(当然......)一旦触发了进程,它就会跳入无限递归:

# 'combo_list' is a list containing the six comboboxes

def changed_single_score(self, source_combo, all_scores, combo_list, indx_in_combo_list):
    scores = all_scores.split(', ')
    for i in range(6):
        selected = self.get_active_text(combo_list[i])
        if selected in scores:
            scores.remove(selected)

    # 'scores' only contains the items that are still available
    for indx in range(6):
        # don't change the box which triggered the update
        if not indx == indx_in_combo_list:
            # the idea is to clear each list and then repopulate it with the
            # remaining available items
            combo_list[indx].get_model().clear()

            for item in scores:
                combo_list[indx].append_text(item)

            # '0' is appended so that swapping values is still possible
            combo_list[indx].append_text('0')

当其中一个组合框发生变化时调用上述函数:

for indx in range(6):
    for score in self.selected['scores'].split(', '):
        combo_list[indx].append_text(score)

    combo_list[indx].connect('changed', self.changed_single_score, self.selected['scores'], combo_list, indx)

也许我应该提一下,我是 Python、OOP 的新手,对 GUI 编程也很陌生。我在这里可能真的很愚蠢,和/或忽略了明显的解决方案,但到目前为止,我一直无法弄清楚如何阻止每个盒子在其自身更新后触发所有其他盒子的更新。

提前感谢您的回复 - 任何帮助将不胜感激。

【问题讨论】:

    标签: python recursion pygtk exit


    【解决方案1】:

    解决此类问题的最简单方法通常是确定您是否需要更改对象的内容(在您的情况下为组合框),然后仅在您实际更改某些内容时才应用更改.这样,您将只传播更新事件,只要它们做某事。

    这应该类似于:

    # '0' is appended so that swapping values is still possible
    items = [item for item in scores] + ['0']
    
    for indx in range(6):
        # don't change the box which triggered the update
        if not indx == indx_in_combo_list:
            # I'm not 100% sure that this next line is correct, but it should be close
            existing_values = [model_item[0] for model_item in combolist[indx].get_model()]
    
            if existing_values != items:
                # the idea is to clear each list and then repopulate it with the
                # remaining available items
                combo_list[indx].get_model().clear()
                for item in items:
                    combo_list[indx].append_text(item)
    

    这是一种非常通用的方法(甚至一些构建系统也使用它)。主要要求是事情确实解决了。在你的情况下,它应该立即解决。

    【讨论】:

    • @canavanin 我没有把它包括在内,因为我已经有一段时间没有用 pygtk 小部件做任何事情了,但我相信你会这样做:existing_values = [model_item[0] for model_item in combolist[indx].get_model()]
    猜你喜欢
    • 2020-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    相关资源
    最近更新 更多