Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 20, 2008 11:15:02

The gray Cardinal
От:
Зарегистрирован: 2007-03-07
Сообщения: 422
Репутация: +  0  -
Профиль   Отправить e-mail  

Запуск скрипта Tkinter из-под Emacs

Простейший пример скрипта на Tkinter (“hello world” практически), создаёт окно с кнопкой “Завершение работы”.

#!/usr/bin/python
# -*- coding: utf-8 -*-
from Tkinter import *
import sys

# функция обработки события для кнопки
def die(event):
sys.exit()

root = Tk() # создаётся главное окно
button = Button(root) # создаётся кнопка в главном окне
button["text"] = u"Завершение работы" # объект кнопки обрабатывается как словарь

button.bind("<Button-1>", die) # регистрация события нажатия первой кнопки мыши
# первый строковый параметр задаёт имя события
# второй параметр указывает имя функции обработки события,
# которая может принимать единственный параметр — event (событие)

# есть альтернативный способ определения функции обработки события:
# button["command"] = die
# при таком подходе параметр event в функции обработки события
# никогда не используется (и не должен быть указан в описании самой функции)

button.pack() # элемент упаковывается в родительском контейнере
root.mainloop() # запуск главного окна и цикла его событий
При запуске в терминале или двойным щелчком в Nautilus, кажется, всё нормально.
При запуске из-под Emacs (C-c C-c) после нажатия на кнопку в окне скрипта “Завершение работы” выдаёт такое:
>>> Traceback (most recent call last):
File “/tmp/py6882Ofk”, line 25, in <module>
root.mainloop() # запуск главного окна и цикла его событий
File “/usr/lib/python2.5/lib-tk/Tkinter.py”, line 1023, in mainloop
self.tk.mainloop(n)
File “/usr/lib/python2.5/lib-tk/Tkinter.py”, line 1405, in __call__
raise SystemExit, msg
SystemExit
>>>
Что это и как с этим бороться?



Офлайн

#2 Окт. 20, 2008 15:37:17

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

Запуск скрипта Tkinter из-под Emacs

1. Зачем такое извращение как event? можно же просто button = Button(root,command=die)
2. Попробуй sys.exit(0) сделать
Добавлено:
а можно и так попробовать:

from Tkinter import *
root=Tk()
def die():
root.destroy() # Уничтожаем родителькое окно, вместе с тем mainloop выходим из mainloop

b=Button(root,text='hello',command=die)
b.pack()
root.mainloop()



Отредактировано (Окт. 20, 2008 15:47:02)

Офлайн

#3 Окт. 20, 2008 15:51:14

The gray Cardinal
От:
Зарегистрирован: 2007-03-07
Сообщения: 422
Репутация: +  0  -
Профиль   Отправить e-mail  

Запуск скрипта Tkinter из-под Emacs

igor.kaist
1. Зачем такое извращение как event? можно же просто button = Button(root,command=die)
2. Попробуй sys.exit(0) сделать
Оба пункта не меняют вообще ничего.
Извращение “event” позволяет получить аргумент в функцию-обработчик, которым там можно при желании пользоваться.
Кстати, после второго нажатия на кнопку в окне скрипта “Завершение работы” emacs в буфере *Python* выдаёт “Process Python finished”. Может, из-под emacs принципиально нельзя использовать “sys.exit()”?



Офлайн

#4 Окт. 20, 2008 16:00:45

The gray Cardinal
От:
Зарегистрирован: 2007-03-07
Сообщения: 422
Репутация: +  0  -
Профиль   Отправить e-mail  

Запуск скрипта Tkinter из-под Emacs

Спасибо, “destroy” помогло.
Выходит, “sys.exit()” emacs действительно неадекватно воспринимает.



Офлайн

#5 Окт. 20, 2008 16:11:30

The gray Cardinal
От:
Зарегистрирован: 2007-03-07
Сообщения: 422
Репутация: +  0  -
Профиль   Отправить e-mail  

Запуск скрипта Tkinter из-под Emacs

Но кстати, вот это в emacs тоже адекватно не работает:

#!/usr/bin/python
# -*- coding: utf-8 -*-
from Tkinter import *

# функция обработки события для кнопки
def die(event):
root.destroy() # уничтожаем родителькое окно, и вместе с тем выходим из цикла его событий

root = Tk() # создаётся главное окно
button = Button(root) # создаётся кнопка в главном окне
button["text"] = u"Завершение работы" # объект кнопки обрабатывается как словарь

button.bind("<Button-1>", die) # регистрация события нажатия первой кнопки мыши
# первый строковый параметр задаёт имя события
# второй параметр указывает имя функции обработки события,
# которая может принимать единственный параметр — event (событие)

# есть альтернативный способ определения функции обработки события:
# button["command"] = die
# при таком подходе параметр event в функции обработки события
# никогда не используется (и не должен быть указан в описании самой функции)

button.pack() # элемент упаковывается в родительском контейнере
root.mainloop() # запуск главного окна и цикла его событий
Выдаёт:
>>> invalid command name “.3082336396L”
while executing
“$w cget -state”
(procedure “tk::ButtonDown” line 12)
invoked from within
“tk::ButtonDown .3082336396L”
(command bound to event)



Офлайн

#6 Окт. 20, 2008 16:12:34

The gray Cardinal
От:
Зарегистрирован: 2007-03-07
Сообщения: 422
Репутация: +  0  -
Профиль   Отправить e-mail  

Запуск скрипта Tkinter из-под Emacs

Блин, а как вообще в emacs работать-то?



Офлайн

#7 Окт. 20, 2008 20:29:15

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

Запуск скрипта Tkinter из-под Emacs

Мне кажется что проблема всетаки в эвенте…
Всетаки гламурнее сделать так :)

#-*- coding:utf-8-*-
from Tkinter import *
root=Tk()
def die(event):
print event # вот тебе и замена эвента, можешь хоть в одном хендлере обрабатывать все кнопки
root.destroy()

b=Button(root,text='Кнопка',command=lambda: die('Я кнопка 1'))
b.pack()
b2=Button(root,text='Еще кнопка',command=lambda: die('Я кнопка 2'))
b2.pack()
root.mainloop()
Тем более у тебя ошибки не в emacs а в Tcl/Tk… Какие то несостыковки в событиях…



Отредактировано (Окт. 20, 2008 20:30:56)

Офлайн

#8 Окт. 20, 2008 21:58:18

The gray Cardinal
От:
Зарегистрирован: 2007-03-07
Сообщения: 422
Репутация: +  0  -
Профиль   Отправить e-mail  

Запуск скрипта Tkinter из-под Emacs

Дело не формально в event'е, потому что вот это в emacs работает правильно:

#!/usr/bin/python
# -*- coding: utf-8 -*-
from Tkinter import *

tk = Tk()
txt = Text(tk)
txt.pack()

def event_info(event):
txt.delete("1.0", END) # очистка с начала до конца текста
for k in dir(event): # цикл по атрибутам события
if k[0] != "_": # берутся только неслужебные атрибуты
# готовится описание атрибута события
ev = "%15s: %s\n" % (k, repr(getattr(event, k)))
txt.insert(END, ev) # добавляется в конец текста

txt.bind("<KeyPress>", event_info)
tk.mainloop()
И кстати, это пример того, где твой вариант непригоден вообще ;).



Офлайн

#9 Окт. 20, 2008 23:04:34

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

Запуск скрипта Tkinter из-под Emacs

Вариант в 7 посте работает?
Ты немного путаешь. Я в tkinter'е вроде от и до разобрался. Много книг даже прочитал :)
у конструктора виджета Button, в отличии от Text есть аргумент command, это не я так придумал.
Подумай сам.. Зачем у баттона есть такой аргумент?? Не просто так же для разнообразия он там..
Во всех туториалах призывают использовать именно этот аргумент почему то. Но мой вариант работает? Уверен что да..
Глянь в профиле мой сайт, там в разделе проекты, есть пару приложений с исходниками, гуи сделаны на тк. На днях появится еще одно. Будет сюрприз для доброй половины пользователей этой гуи библиотеки :)
P.S. Попрошу не пугать меня примерами из интуитовского учебника. Давно уже пройденная тема



Отредактировано (Окт. 20, 2008 23:07:35)

Офлайн

#10 Окт. 21, 2008 09:33:06

The gray Cardinal
От:
Зарегистрирован: 2007-03-07
Сообщения: 422
Репутация: +  0  -
Профиль   Отправить e-mail  

Запуск скрипта Tkinter из-под Emacs

igor.kaist
Вариант в 7 посте работает?
Да, спасибо.
igor.kaist
Зачем у баттона есть такой аргумент?? Не просто так же для разнообразия он там..
Для упрощения кодирования, ну и что?

Это всё не значит, что я не имею права применять bind и event. И это не значит, что я не имею права применять sys.exit().
Код в постах #1 и #5 неверен? Тогда почему он без вопросов работает в консоли? Если этот код верен, то какого … emacs выдаёт ругань?



Отредактировано (Окт. 21, 2008 10:03:42)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version