我正在使用PyGTK和gtk.Assistant小部件。在一个页面上,我有六个组合框,最初具有相同的内容(六个数字)。当用户在其中一个组合框中选择一个数字时,其他五个框中不再有该数字(除非它在原始列表中作为副本存在)。因此,我想永远更新内容。
我尝试了以下方法(这里只是一些代码片段),但是(当然......)一旦触发了进程,它就会跳转到无限递归:
# '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编程的新手。我可能在这里非常愚蠢,和/或忽略了明显的解决方案,但到目前为止我还无法弄清楚如何阻止每个盒子在更新后触发所有其他盒子的更新。
提前感谢您的回复 - 非常感谢任何帮助。
答案 0 :(得分:3)
对于这类问题最简单的解决方法通常是弄清楚你是否需要更改对象的内容(在你的情况下是组合框)然后只在你实际改变某些东西时应用更改。通过这种方式,您只会传播更新事件。
这应该类似于:
# '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)
这是一种非常通用的方法(甚至一些构建系统使用它)。主要要求是事情确实解决了。在你的情况下,它应该立即解决。