更新 PyGTK 组合框时如何保留选择?

发布于 2024-10-08 08:32:28 字数 2745 浏览 5 评论 0原文

这是 的后续内容我昨天问的问题。我想要做的是获取一组 PyGTK 组合框,以便在其中一个组合框中选择某个值时进行更新。最初它们都包含相同的可供选择的项目,但是当选择一个值时,该值不应再在任何其他组合框中可用(除非它在原始列表中作为重复项出现)。

我已经创建了一个应可用于特定组合框的值列表,回答昨天问题的他也好心地为我提供了一种列出框中当前所有现有项目的方法,所以我现在比较“应将“应可用”列表更改为“当前可用列表”,并且仅在这两个列表不同时才更新组合框。一切正常 - 除了以下事实:每当我从组合框中删除旧内容时,所有当前选择都会消失,并且我尝试重新建立选择只会导致无限的相互组合框更新。

我进行了多次搜索,但我发现的方法都不适合我,所以我再次陷入困境,因此如果有人可以帮助我那就太好了。这是我正在使用的代码的当前版本:

# 'combo_list' contains all the comboboxes of interest
# 'indx_in_combo_list' is the index (from 'combo_list') of the combobox which
# triggered the updating process

def changed_single_score(self, source_combo, all_scores, combo_list, indx_in_combo_list):
    # append '0' so that swapping values remains possible
    available_items = all_scores.split(', ') + ['0']

    for i in range(len(combo_list)):
        # make items unavailable that are selected in one of the boxes
        selected = self.get_active_text(combo_list[i])
        if selected in available_items:
            available_items.remove(selected)

    for indx in range(len(combo_list)):
        # don't try changing the combobox which triggered updating
        if indx != indx_in_combo_list:
            existing_items = [model_item[0] for model_item in combo_list[indx].get_model()]
            local_selection = self.get_active_text(combo_list[indx])
            local_available = available_items[:]

            # each box must retain its own selected item
            if local_selection != None:
               local_available.append(local_selection)

            local_available.sort()
            local_available.reverse()
            existing_items.sort()
            existing_items.reverse()

            if existing_items != local_available:

                # if I uncomment the following line the boxes are cleared
                # but all selections vanish, too
                #combo_list[indx].get_model().clear()

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

                # I want to make sure that the selection is retained,
                # but if I do it like this I just cause emission of the
                # 'changed' signal, thus I get infinite recursion again
                #if local_selection != None:
                #    combo_list[indx].set_active(local_available.index(local_selection))

上面的函数在以下上下文中调用:

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

我还尝试一一删除所有旧条目并仅保留所选条目,但这也不起作用。我可能再次忽略了显而易见的解决方案,但如果这里有人能向我指出那就太好了!

预先非常感谢。

This is a follow-up to a question I asked yesterday. What I want to do is to get a set of PyGTK-comboboxes to get updated whenever a value is selected in one of them. Initially they all contain the same items to choose from, but when a value is selected this value should no longer be available in any of the other comboboxes (unless it's present as a duplicate in the original list).

I have got as far as creating a list of the values which should be available for a particular combobox, and he who answered yesterday's question also kindly provided me with a way of listing all currently existing items in the box, so I now compare the 'should be available' list to the 'currently available list' and only set out to update a combobox if those two lists differ. Everything works well - apart from the fact that whenever I remove the old contents from a combobox all current selections vanish, and my attempts to re-establish the selection have just led to infinite mutual combobox-updating.

I have conducted several searches, but none of the methods I found have worked for me, so again I'm at my wit's end, thus it would be great if someone could help me out. Here's the current version of the code I'm using:

# 'combo_list' contains all the comboboxes of interest
# 'indx_in_combo_list' is the index (from 'combo_list') of the combobox which
# triggered the updating process

def changed_single_score(self, source_combo, all_scores, combo_list, indx_in_combo_list):
    # append '0' so that swapping values remains possible
    available_items = all_scores.split(', ') + ['0']

    for i in range(len(combo_list)):
        # make items unavailable that are selected in one of the boxes
        selected = self.get_active_text(combo_list[i])
        if selected in available_items:
            available_items.remove(selected)

    for indx in range(len(combo_list)):
        # don't try changing the combobox which triggered updating
        if indx != indx_in_combo_list:
            existing_items = [model_item[0] for model_item in combo_list[indx].get_model()]
            local_selection = self.get_active_text(combo_list[indx])
            local_available = available_items[:]

            # each box must retain its own selected item
            if local_selection != None:
               local_available.append(local_selection)

            local_available.sort()
            local_available.reverse()
            existing_items.sort()
            existing_items.reverse()

            if existing_items != local_available:

                # if I uncomment the following line the boxes are cleared
                # but all selections vanish, too
                #combo_list[indx].get_model().clear()

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

                # I want to make sure that the selection is retained,
                # but if I do it like this I just cause emission of the
                # 'changed' signal, thus I get infinite recursion again
                #if local_selection != None:
                #    combo_list[indx].set_active(local_available.index(local_selection))

The above function is called in the following context:

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

I also tried deleting all old entries one by one and just keeping the one with the selection, but that didn't work either. I'm probably overlooking the obvious solution again, but if someone here could point it out to me that would be great!

Thanks a lot in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

没企图 2024-10-15 08:32:28

您可以在函数顶部使用布尔值锁定代码,以免在填充组合框时由将调用该代码的附加信号执行。

if self.changed_single_score_locked:
    return
else:
    self.changed_single_score_locked = True
  1. 存储所选择的内容
  2. 清除框
  3. 重新填充
  4. 选择所选择的内容

然后删除函数末尾的锁:

self.changed_single_score_locked = False

或者可能使用 GTK API 通过其他方式完全关闭信号?

编辑:改用 handler_block 。

You could lock the code with a boolean in the top of your function from being executed by the additional signals that will call it while you fill the combo boxes.

if self.changed_single_score_locked:
    return
else:
    self.changed_single_score_locked = True
  1. store what was selected
  2. clear box
  3. repopulate
  4. select what was selected

Then remove the lock at the end of the function:

self.changed_single_score_locked = False

Or maybe shut down the signal completely by some other means using the GTK API?

Edit: Use handler_block instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文