#python #user-interface #gtk #pygtk
#python #пользовательский интерфейс #gtk #pygtk
Вопрос:
У меня есть три кнопки PyGTK SpinButtons, которые взаимно зависят друг от друга: назовите их A, B и C. Есть еще одна кнопка D, которая переключается между двумя взаимными определениями C, так что значение C определяется как A / B, если D не было нажато нечетное число раз.
Я хочу иметь возможность, например, изменять A и немедленно обновлять B или C в соответствии с этой взаимосвязью. Я также хочу иметь возможность изменять B и немедленно обновлять или C. То же самое касается C. Я решил, что при изменении одной из них следует обновить SpinButton, которая была изменена наименее недавно, и что, если никакие SpinButtons не были изменены с момента запуска программы, следует предположить, что C был изменен совсем недавно.
Все вышеперечисленное было реализовано. Мое приложение прослушивает сигналы изменения значения для каждой из кнопок вращения, выполняет приведенные выше вычисления, а затем обновляет значение двух других, как описано. Однако приложение распознает свои собственные изменения и реагирует на них. Когда я изменяю A, моя программа изменяет B, которая обрабатывается изменением C, и так далее. Я также пробовал сигнал изменения значения, но он не реагирует на изменения в кнопке вращения.
Как мне отслеживать изменение значения SpinButton таким образом, чтобы это не было вызвано самой программой?
Ответ №1:
Вы можете отключить обработчик сигналов для данного счетчика перед его вызовом set_value
. Это гарантирует, что сигнал запускается только в ответ на события мыши и клавиатуры, а не программные изменения. Вот краткий пример:
import pygtk, gtk
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.connect('destroy', lambda w: gtk.main_quit())
def _add_spinner():
adj = gtk.Adjustment(0.0, -100.0, 100.0, 1.0, 2.0, 0.0)
spin = gtk.SpinButton(adj, 0, 1)
spin.set_wrap(True)
hbox.pack_start(spin, True, True, 10)
return spin
vbox = gtk.VBox(True, 10)
hbox = gtk.HBox(True, 10)
vbox.pack_start(hbox, True, True, 10)
spin1 = _add_spinner()
spin2 = _add_spinner()
win.add(vbox)
def set_spin(src, dst):
# ensure that calling `set_value` does not fire events
hid = handlers.get(dst)
dst.handler_block(hid)
dst.set_value(src.get_value() 1.5)
dst.handler_unblock(hid)
# when 'spinN' is changed, call 'set_spin'
hid1 = spin1.connect('value-changed', set_spin, spin2)
hid2 = spin2.connect('value-changed', set_spin, spin1)
handlers = {spin1: hid1, spin2: hid2}
win.show_all()
gtk.main()