Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 4, 2014 19:32:49

noob_saibot
Зарегистрирован: 2013-09-11
Сообщения: 495
Репутация: +  20  -
Профиль   Отправить e-mail  

Tkinter focus_force

from Tkinter import *
root = Tk()
root.after(5000, lambda: root.focus_force())
root.mainloop()
С lambda отрабатывает на уже открытом окне, без него окно открывается просто через 5 секунд.

“lambda param_list: expression
Короткая форма создания (безымянной) функции, возвращающей значение выра-
жения expression. Ее поведение аналогично поведению функции, созданной с
помощью инструкции ‘def name(param_list): return expression’.”
- Г. Россум, Ф.Л.Дж. Дрейк, Д.С.Откидач
Язык программирования Python.

Но:
from Tkinter import *
root=Tk()
def lol():
    return root.focus_force()
root.after(5000, lol())
root.mainloop()
отрабатывает также как и без lambda (тоесть открывает окно через 5 секунд). Или я что-то не уловил и записал неправильно?

Отредактировано noob_saibot (Апрель 4, 2014 19:33:28)

Офлайн

#2 Апрель 5, 2014 11:34:40

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter focus_force

Я вообще не понял вопроса. Что Вы хотите выяснить?

Офлайн

#3 Апрель 6, 2014 14:17:12

noob_saibot
Зарегистрирован: 2013-09-11
Сообщения: 495
Репутация: +  20  -
Профиль   Отправить e-mail  

Tkinter focus_force

4kpt_II
Я вообще не понял вопроса. Что Вы хотите выяснить?
1. Почему без lambda root.after не отрабатывает как надо?
from Tkinter import *
root = Tk()
root.after(5000, lambda: root.focus_force())
root.mainloop()
2. Правильно ли я заменил lambda?
from Tkinter import *
root=Tk()
def lol():
    return root.focus_force()
root.after(5000, lol())
root.mainloop()

Отредактировано noob_saibot (Апрель 6, 2014 14:17:32)

Офлайн

#4 Апрель 6, 2014 14:20:01

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter focus_force

А что Вы хотите реализовать?

Офлайн

#5 Апрель 6, 2014 14:25:46

noob_saibot
Зарегистрирован: 2013-09-11
Сообщения: 495
Репутация: +  20  -
Профиль   Отправить e-mail  

Tkinter focus_force

4kpt_II
А что Вы хотите реализовать?
Мне надо чтобы сразу открывалось окно, далее через 5 секунд отрабатывал focus_force.
Я так понял .after как раз для этого и нужен
И разобраться с lambda. Правильно ли я усвоил её назначение.

Отредактировано noob_saibot (Апрель 6, 2014 14:27:39)

Офлайн

#6 Апрель 6, 2014 14:29:35

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter focus_force

Понял. Теоретически нужно так, но у меня root всегда отрабатывает в фокусе, поэтому не могу проверить:

from Tkinter import *
#
root = Tk()
#
def lol():
    root.focus_force()
#
root.after(5000, lol)
root.mainloop()

Ну и напоминаю, что

from Tkinter import*

Так делать нельзя ни в коем случае.

P.S. Будут вопросы - пишите…

Офлайн

#7 Апрель 6, 2014 15:13:53

noob_saibot
Зарегистрирован: 2013-09-11
Сообщения: 495
Репутация: +  20  -
Профиль   Отправить e-mail  

Tkinter focus_force

Вот нашёл.

    def after(self, ms, func=None, *args):
        """Call function once after given time.
        MS specifies the time in milliseconds. FUNC gives the
        function which shall be called. Additional parameters
        are given as parameters to the function call.  Return
        identifier to cancel scheduling with after_cancel."""
        if not func:
            # I'd rather use time.sleep(ms*0.001)
            self.tk.call('after', ms)
        else:
            def callit():
                try:
                    func(*args)
                finally:
                    try:
                        self.deletecommand(name)
                    except TclError:
                        pass
            name = self._register(callit)
            return self.tk.call('after', ms, name)
root.after воспринимает root.focus_forse() как not func и отрабатывает так:
if not func:
            # I'd rather use time.sleep(ms*0.001)
            self.tk.call('after', ms)
Вот почему без lambda нельзя

Отредактировано noob_saibot (Апрель 6, 2014 15:14:25)

Офлайн

#8 Апрель 6, 2014 15:38:31

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter focus_force

Что Вы имеете ввиду? Можно без lambda.
Просто в первом посту Вы передавали не объект функции, а объект результата ее выполнения. Поэтому и не работало.

Так неверно в принципе:

root.after(5000, lol())

Так Вы передаете в обработчик не функцию, а результат ее выполнения.

Нужно всегда делать так:

root.after(5000, lol)

В этом случае Вы передаете в обработчик функцию. Это касается как метода .after так и других методов. В частности .bind в первом случае тоже выполнятся не будет.

А вот lambda нужна тогда, когда вы хотите еще в эту функцию что-то передать. В этом случае, если Вы опять напишите

root.after(5000, lol(12))

То опять свяжите обработчик с результатом выполнения, что Вам не подходит.
Поэтому делается через анонимную функцию:

root.after(5000, lambda: lol(12))

P.S. Будут вопросы - пишите…

P.S.S. Вообще желательно по tkinter в ветке GUI

Отредактировано 4kpt_II (Апрель 6, 2014 15:47:08)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version