Python: как мне обойти переменные переменные - PullRequest
1 голос
/ 25 октября 2011

Поскольку Питон - мой первый ОО-язык, я не могу понять. Мне нужно запустить диалог и поместить возвращаемое значение в переменную, переданную из другой функции. Как мне обойти переменные переменные в этом случае, в dGetPath?

def dGetPath(self, widget, data=None):
    print "%s needs to be filled with output from a dialog here" % (data)

def dupChk(self, widget, data=None):
    print "if I figure out dGetPath... %s should be easy" % (data)

def __init__(self):
    self.mainwin = gtk.Window(gtk.WINDOW_TOPLEVEL)
    self.mainwin.set_position(gtk.WIN_POS_CENTER)
    # ...
    self.Apath = gtk.Button("A in path")
    self.Apath.connect("clicked", self.dGetPath, "Apath")

    self.Aopath = gtk.Button("A out path")
    self.Aopath.connect("clicked", self.dGetPath, "Aopath")

    self.dupchkA = gtk.Button("Dupe check A")  # check A path for duplicates
    self.dupchkA.connect("clicked", self.dupChk, "dupchkA")
    self.dupchkA.set_tooltip_text("check A path for duplicates using MD5 sum")

    self.Bpath = gtk.Button("B in path")
    self.Bpath.connect("clicked", self.dGetPath, "Bpath")

    self.Bopath = gtk.Button("B out path")
    self.Bopath.connect("clicked", self.dGetPath, "Bopath")

    self.dupchkB = gtk.Button("Dupe check B")  # check B path for duplicates
    self.dupchkB.connect("clicked", self.dupChk, "dupchkB")
    self.dupchkA.set_tooltip_text("check B path for duplicates using MD5 sum")
    # ...

1 Ответ

2 голосов
/ 25 октября 2011

Если я правильно прочитал ваш вопрос, вы запутались в обработке событий и функциях обратного вызова - вам нужно сделать что-то (dupChk())на значение, возвращаемое из диалогового окна (еще не определено ...), когда пользователь нажимает Apath.

То, что я считаю , которого вам не хватает, - это место для храненияфайл или каталог, выбранный filechooser (self.APath?) - и необходимость создавать диалоговое окно filechooser при нажатии кнопки.

Но ваша кнопка Apath еще не знает путь, поэтому вы не можете назначить ей функцию обратного вызова, которая работает на пути.Вы можете:

  • дать в качестве функции обратного вызова функцию, которая открывает диалоговое окно для выбора файлового файла, а затем вызывает функцию dupChk() для результата.

  • *У 1027 * есть средство выбора файлов, доступное через какой-то другой механизм (еще одна кнопка - встроенная в окно, всегда открытое - текстовое поле, подходящее только для ввода текста), и повторно пометите свою Apath кнопку «Проверить A на наличие дубликатов».Функция обратного вызова filechooser сохраняется в self.Apath, а функция обратного вызова кнопки вызывает dupChk(self.Apath).

Обновление

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

Объектно-ориентированное программирование - это просто способ связать пользовательские типы с действиями над этими типами.Вы создаете Window объект для хранения атрибутов, связанных с окном и методами, которые работают с конкретным Window объектом.Или вы создаете объект Widget, который предоставляет данные , общие для всех графических виджетов - положение X, положение Y, ширина, высота, независимо от того, может ли виджет увеличиваться или уменьшаться в измерениях X или Y, видимым илиневидимые и т. д., и операции , общие для всех виджетов - установка положения X или Y, ширины, высоты, элементов управления ростом и уменьшением, видимых или невидимых и т. д. Затем каждый новыйграфический элемент наследует от базовой функции Widget и затем может предоставлять новые данные или операции, относящиеся к новому типу создаваемого виджета.

Чтобы отдельные графические элементы управления были простыми, большинствоНаборы инструментов программирования GUI предоставляют событий , которые каждый графический элемент может генерировать или потреблять.Вы предоставляете callbacks - функции, которые вызываются при возникновении событий.Большинство сред программирования GUI работают совсем не так, как «обычное» программирование;разницу иногда называют инверсией управления .По сути, инструментарий GUI настраивает все, а затем вызывает функции, которые вы предоставляете.(Ваша main() или, в данном случае, функция __init__() просто устанавливает все виджеты и обратные вызовы, а затем запускает цикл обработки событий , который ожидает события, затем вызывает ваши функции обратного вызова.)

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

В отличие от Java, в Python не все нуждается в внутри класса.Если верхний уровень вашей программы не заслуживает того, чтобы быть в классе, вам не нужно помещать его в класс.Вы могли бы хотеть поместить все это в класс в любом случае, так что легче встраивать в будущие программы, но если эта программа просто нуждается в решении небольшой задачи и, вероятно, не будет встроена, в этом нет необходимостичрезмерно усложнять задачу программирования.Имея это в виду, я написал маленький (и не особенно симпатичный) маленький демонстрационный инструмент, который показывает, как отображать два FileChooserButtons, как подключиться к их "file-set" сигналу, как получитьимя файла из рассматриваемого средства выбора файлов, и как сохранить результаты из средства выбора файлов в переменную по вашему выбору.

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

char *filea, *fileb;
hyptothetical_widget widget = new_hypothetical_widget("foo");
hypthetical_connect(widget, &callback, &filea);

и &filea (или &fileb) будет достаточно, чтобы выбрать, какой указатель вы хотите обновить.

Python делает это немного хитро - нет способа просто добавить & для передачи указателя.То, что вы можете сделать - это передать массив и изменить массив в обратном вызове .

Небольшая демонстрация, которую я написал, использует этот трюк "передача по ссылке", чтобы сделать еголегко использовать одну и ту же функцию обратного вызова для записи в две различных переменных в зависимости от того, к какому виджету он был подключен:

#!/usr/bin/python

import gtk

def pick_file(widget, filename):
    filename[0] = widget.get_filename()
    print filename
    update_entry_boxes()

def update_entry_boxes():
    ea.set_text(filea[0])
    eb.set_text(fileb[0])



filea=["None Selected"]
fileb=["None Selected"]

win = gtk.Window(gtk.WINDOW_TOPLEVEL)
box = gtk.HBox();

ba = gtk.FileChooserButton("File A")
ba.connect("file-set", pick_file, filea)
bb = gtk.FileChooserButton("File B")
bb.connect("file-set", pick_file, fileb)
ea = gtk.Entry()
eb = gtk.Entry()

box.add(ba)
box.add(ea)
box.add(bb)
box.add(eb)

update_entry_boxes()

win.add(box)
win.show_all()

gtk.main()

Надеюсь, это полезно.

...