当Python对象触发彼此的更新时,如何停止无限递归? [英] How to stop infinite recursion when Python objects trigger each other's updates?

查看:149
本文介绍了当Python对象触发彼此的更新时,如何停止无限递归?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using PyGTK and the gtk.Assistant widget. On one page I have six comboboxes, which initially have the same contents (six numbers). When the users selects a number in one of those comboboxes, this number should no longer be available in the other five boxes (unless it's present as a duplicate in the original list). Hence I would like to always update the contents.

我尝试了以下方法(此处仅提供了一些代码片段),但是(当然...)一旦触发了该过程,它就会跳入无限递归:

I have tried the following approach (just a few code snippets here), but (of course...) it just jumps into infinite recursion once the process has been triggered:

# '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')

当其中一个组合框发生更改时,将调用上述函数:

The above function is called when a change occurs in one of the comboboxes:

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编程的新手.我可能在这里真的很愚蠢,并且/或者忽略了显而易见的解决方案,但是到目前为止,我还无法弄清楚一旦它本身被更新,如何阻止每个盒子触发所有其他盒子的更新.

Perhaps I ought to mention that I'm new to Python, OOP, and also rather new to GUI-programming. I'm probably being really stupid here, and/or overlooking the obvious solution, but I have so far been unable to figure out how to stop each box from triggering updating of all other boxes once it itself has been updated.

在此先感谢您的答复-非常感谢您的帮助.

Thanks in advance for your replies - any help would be greatly appreciated.

推荐答案

这种问题的最简单解决方法通常是确定您是否需要更改对象的内容(组合框,大小写),然后仅在您实际进行更改时才应用更改.这样,您只会传播更新事件的作用范围.

The simplest fix for this sort of problem is generally to figure out if you're going to need to change the contents of the object (the combobox, in your case) and then only apply changes if you're actually changing something. This way you'll only propagate update events as far as they do something.

这应该类似于:

# '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)

这是一种非常通用的方法(即使某些构建系统也使用它).主要要求是事情确实会解决.您的情况应该立即解决.

This is a pretty general approach (even some build systems use it). The main requirement is that things actually do settle. In your case it should settle immediately.

这篇关于当Python对象触发彼此的更新时,如何停止无限递归?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆