Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 8, 2014 21:30:23

vanvanov
Зарегистрирован: 2013-03-31
Сообщения: 252
Репутация: +  4  -
Профиль   Отправить e-mail  

Окно Tkinter неактивно

Есть такой код:

#!/usr/bin/python3
import tkinter as tk
# Текстовое поле в одну строку
def test_gui():
	top, res = tk.Toplevel(root), [None]
	def callback():
		res[0] = entry.get()
		top.destroy()
		root.deiconify()
	root.withdraw()
	entry=tk.Entry(top)
	entry.pack()
	entry.bind('<Return>', lambda e: callback())
	entry.focus_set()
	top.wait_window(top)
	return res[0]
root=tk.Tk()
test_gui()
test_gui()
test_gui()
root.mainloop()

Объясните, пожалуйста, почему в Linux новое создаваемое в test_gui() окно всегда является активным, а в Windows активным является только 1-е окно, а все остальные окна, хоть и выходят на передний план, но не являются активными - для их активизации на них нужно переключиться по Alt+Tab или мышью?

Какая структура программы была бы правильной? Правильно ли я использую withdraw?

Офлайн

#2 Окт. 9, 2014 00:16:07

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

Окно Tkinter неактивно

Давайте лучше проще. Что нужно сделать. Что делаете и в чем проблема…

Офлайн

#3 Окт. 9, 2014 14:35:25

vanvanov
Зарегистрирован: 2013-03-31
Сообщения: 252
Репутация: +  4  -
Профиль   Отправить e-mail  

Окно Tkinter неактивно

4kpt_II
Давайте лучше проще. Что нужно сделать. Что делаете и в чем проблема…
Есть программа, выполняющее множество действий, в том числе, отображение маленького окошка с возможностью ввода текста, отображение большого окна с возможностью ввода текста, отображение окна с текстом и пр. Проблема в том, что данный код (как и код, приведенный в примере) работает по-разному на разных платформах. На Linux все работает как надо. На Windows после разрушения второстепенного (модального) окна Top фокус при создании другого окна Top почему-то возвращается к root. В итоге, Top висит на экране, но оно почему-то неактивно. Ввести в него что-то можно, только нажав на него мышью или выбрав по Alt+Tab. Окно root для программы бесполезно, все реализовано в Top. Поэтому окно root скрывается путем withdraw. Если же его не скрывать, то оно всегда всплывет раньше Top и перехватит фокус на себя.

В разделе GUI на этом форуме была похожая тема. Однако, top.focus_set(), top.focus_force(), top.grab_set() не всегда срабатывают. Укажите, пожалуйста, что нужно добавить в вышеприведенном примере в функцию test_gui(), чтобы окно Top не позволяло рутовому окну перехватывать фокус на себя.

Для ясности сделал два скриншота. Вот это первое выполнение test_gui().
Вот это второе и последующее выполнение того же test_gui().
Как видно, во втором случае окно Top неактивно. Почему? Как исправить?

Отредактировано vanvanov (Окт. 9, 2014 14:59:27)

Офлайн

#4 Окт. 10, 2014 11:39:30

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

Окно Tkinter неактивно

Используйте focus_force(). Ну и сама конструкция по возврату значения немножко корявенькая

import Tkinter as tk
# Текстовое поле в одну строку
def test_gui():
    top, res = tk.Toplevel(root), [None]
    def callback():
        res[0] = entry.get()
        top.destroy()
        root.deiconify()
    root.withdraw()
    entry=tk.Entry(top)
    entry.pack()
    entry.bind('<Return>', lambda e: callback())
    entry.focus_force()
    tk.Button(top, text="close", command=lambda: root.destroy()).pack()
    top.wait_window(top)
root=tk.Tk()
test_gui()
test_gui()
test_gui()
test_gui()
root.mainloop()

P.S. Проверено на winXP.
P.S.S. Еще можно посмотреть в сторону параметра toplevel - “takefocus”…

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version