Как сохранить выделение при обновлении комбинированного списка PyGTK? - PullRequest
2 голосов
/ 19 декабря 2010

Это продолжение вопроса , который я задал вчера.Я хочу получить набор 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)

Я также попытался удалить все старые записи одну за другойи просто сохранить один с выбором, но это тоже не сработало.Я, вероятно, снова упускаю из виду очевидное решение, но если бы кто-то здесь мог указать мне, это было бы здорово!

Заранее большое спасибо.

1 Ответ

1 голос
/ 20 декабря 2010

Вы можете заблокировать код с логическим значением в верхней части вашей функции, чтобы он не выполнялся дополнительными сигналами, которые будут вызывать его при заполнении полей со списком.

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.

...