Запрос информации от пользователя внутри основного цикла GTK - PullRequest
3 голосов
/ 19 мая 2010

Я изучаю Python, создав простое приложение PyGTK, которое извлекает данные из некоторых репозиториев SVN, используя pysvn . Клиент pysvn имеет callback , который вы можете указать, что он вызывает, когда Subversion требуется информация для аутентификации для хранилища. Когда это произойдет, я хотел бы открыть диалоговое окно, чтобы попросить пользователя ввести учетные данные.

Проблема в том, что обратный вызов вызывается внутри основного цикла GTK, поэтому он в основном вызывается при каждом тике. Есть ли способ предотвратить это? Возможно, открыв диалог в новой теме? Но тогда как мне вернуть кортеж с пользовательскими данными в обратный вызов, чтобы он мог вернуть его в pysvn.Client?

1 Ответ

1 голос
/ 26 мая 2010

Это то, как мы делаем это в RabbitVCS. По сути, основное приложение создает диалоговое окно и запускает его, используя метод PyGTK gtk.Dialog run () .

Разбираем его из основного приложения (см. action.py ):

def get_login(self, realm, username, may_save):

    # ...other code omitted...

    gtk.gdk.threads_enter()
    dialog = rabbitvcs.ui.dialog.Authentication(
        realm,
        may_save
    )
    result = dialog.run()
    gtk.gdk.threads_leave()

    return result

Эта функция "get_login" является , заданной в качестве обратного вызова для экземпляра клиента PySVN.

Обратите внимание на методы threads_enter () и threads_leave () ! Это позволяет GTK использовать потоки Python, но учтите, что GIL может быть заблокирован другими расширениями.

Для этого создается диалоговое окно (уже размеченное с использованием Glade ), а метод run () этого класса является оберткой для метода PyGTK (см. dialog.py * 1023). *):

def run(self):
    returner = None
    self.dialog = self.get_widget("Authentication")
    result = self.dialog.run()

    login = self.get_widget("auth_login").get_text()
    password = self.get_widget("auth_password").get_text()
    save = self.get_widget("auth_save").get_active()
    self.dialog.destroy()

    if result == gtk.RESPONSE_OK:
        return (True, login, password, save)
    else:
        return (False, "", "", False)

Код пользовательского интерфейса RabbitVCS, вероятно, гораздо более запутанный, чем вам нужно, но он может помочь разобраться. Эти вызовы get_widget являются удобными методами для получения виджета из дерева Glade. Если вы не используете Glade, у вас будут ссылки на виджеты напрямую.

Надеюсь, это поможет:)

...