Как сделать незакрываемое окно в python

Обновлено: 30.04.2024

В этом уроке мы узнаем, как разрабатывать графические пользовательские интерфейсы, с помощью разбора некоторых примеров графического интерфейса Python с использованием библиотеки Tkinter.

Библиотека Tkinter установлена в Python в качестве стандартного модуля, поэтому нам не нужно устанавливать что-либо для его использования. Tkinter — очень мощная библиотека. Если вы уже установили Python, можете использовать IDLE, который является интегрированной IDE, поставляемой в Python, эта IDE написана с использованием Tkinter. Звучит круто!

Мы будем использовать Python 3.7 поэтому, если вы все еще используете Python 2.x, настоятельно рекомендуем перейти на Python 3.x, если вы не в курсе нюансов изменения языка, с целью, чтобы вы могли настроить код для запуска без ошибок.

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

Создание своего первого графического интерфейса

Для начала, следует импортировать Tkinter и создать окно, в котором мы зададим его название:

Обучение Python GUI (уроки по Tkinter)

Результат будет выглядеть следующим образом:
Прекрасно! Наше приложение работает.
Последняя строка вызывает функцию mainloop . Эта функция вызывает бесконечный цикл окна, поэтому окно будет ждать любого взаимодействия с пользователем, пока не будет закрыто.

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

Создание виджета Label

Чтобы добавить текст в наш предыдущий пример, мы создадим lbl , с помощью класса Label , например:

Затем мы установим позицию в окне с помощью функции grid и укажем ее следующим образом:

Полный код, будет выглядеть следующим образом:

Обучение Python GUI (уроки по Tkinter)

И вот как будет выглядеть результат:
Если функция grid не будет вызвана, текст не будет отображаться.

Настройка размера и шрифта текста

Вы можете задать шрифт текста и размер. Также можно изменить стиль шрифта. Для этого передайте параметр font таким образом:

Обучение Python GUI (уроки по Tkinter)

Обратите внимание, что параметр font может быть передан любому виджету, для того, чтобы поменять его шрифт, он применяется не только к Label .

Отлично, но стандартное окно слишком мало. Как насчет настройки размера окна?

Настройка размеров окна приложения

Мы можем установить размер окна по умолчанию, используя функцию geometry следующим образом:

В приведенной выше строке устанавливается окно шириной до 400 пикселей и высотой до 250 пикселей.

Попробуем добавить больше виджетов GUI, например, кнопки и посмотреть, как обрабатывается нажатие кнопок.

Добавление виджета Button

Начнем с добавления кнопки в окно. Кнопка создается и добавляется в окно так же, как и метка:

Наш код будет выглядеть вот так:

Обучение Python GUI (уроки по Tkinter)

Результат будет следующим:
Обратите внимание, что мы помещаем кнопку во второй столбец окна, что равно 1. Если вы забудете и поместите кнопку в том же столбце, который равен 0, он покажет только кнопку.

Изменение цвета текста и фона у Button

Вы можете поменять цвет текста кнопки или любого другого виджета, используя свойство fg .
Кроме того, вы можете поменять цвет фона любого виджета, используя свойство bg .

Обучение Python GUI (уроки по Tkinter)

Теперь, если вы попытаетесь щелкнуть по кнопке, ничего не произойдет, потому что событие нажатия кнопки еще не написано.

Кнопка Click

Для начала, мы запишем функцию, которую нужно выполнить при нажатии кнопки:

Затем мы подключим ее с помощью кнопки, указав следующую ​​функцию:

Обратите внимание: мы пишем clicked , а не clicked() с круглыми скобками. Теперь полный код будет выглядеть так:

Обучение Python GUI (уроки по Tkinter)

При нажатии на кнопку, результат, как и ожидалось, будет выглядеть следующим образом:
Круто!

Получение ввода с использованием класса Entry (текстовое поле Tkinter)

В предыдущих примерах GUI Python мы ознакомились со способами добавления простых виджетов, а теперь попробуем получить пользовательский ввод, используя класс Tkinter Entry (текстовое поле Tkinter).
Вы можете создать текстовое поле с помощью класса Tkinter Entry следующим образом:

Затем вы можете добавить его в окно, используя функцию grid .
Наше окно будет выглядеть так:

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

Если вы нажмете на кнопку — появится текст «Привет » вместе с введенным текстом в виджете записи. Вот полный код:

Обучение Python GUI (уроки по Tkinter)

Запустите вышеуказанный код и проверьте результат:
Прекрасно!

Каждый раз, когда мы запускаем код, нам нужно нажать на виджет ввода, чтобы настроить фокус на ввод текста, но как насчет автоматической настройки фокуса?

Установка фокуса виджета ввода

Здесь все очень просто, ведь все, что нам нужно сделать, — это вызвать функцию focus :

Когда вы запустите свой код, вы заметите, что виджет ввода в фокусе, который дает возможность сразу написать текст.

Отключить виджет ввода

Чтобы отключить виджет ввода, отключите свойство состояния:

Обучение Python GUI (уроки по Tkinter)

Теперь вы не сможете ввести какой-либо текст.

Добавление виджета Combobox

Чтобы добавить виджет поля с выпадающем списком, используйте класс Combobox из ttk следующим образом:

Затем добавьте свои значения в поле со списком.

Обучение Python GUI (уроки по Tkinter)

Как видите с примера, мы добавляем элементы combobox , используя значения tuple .
Чтобы установить выбранный элемент, вы можете передать индекс нужного элемента текущей функции.
Чтобы получить элемент select , вы можете использовать функцию get вот таким образом:

Добавление виджета Checkbutton (чекбокса)

С целью создания виджета checkbutton , используйте класс Checkbutton :

Кроме того, вы можете задать значение по умолчанию, передав его в параметр var в Checkbutton :

Обучение Python GUI (уроки по Tkinter)

Посмотрите на результат:

Установка состояния Checkbutton

Здесь мы создаем переменную типа BooleanVar , которая не является стандартной переменной Python, это переменная Tkinter, затем передаем ее классу Checkbutton , чтобы установить состояние чекбокса как True в приведенном выше примере.

Вы можете установить для BooleanVar значение false, что бы чекбокс не был отмечен.
Так же, используйте IntVar вместо BooleanVar и установите значения 0 и 1.

Эти примеры дают тот же результат, что и BooleanVar .

Добавление виджетов Radio Button

Чтобы добавить radio кнопки, используйте класс RadioButton :

Обратите внимание, что вы должны установить value для каждой radio кнопки с уникальным значением, иначе они не будут работать.

Обучение Python GUI (уроки по Tkinter)

Результатом вышеприведенного кода будет следующий:
Кроме того, вы можете задать command любой из этих кнопок для определенной функции. Если пользователь нажимает на такую кнопку, она запустит код функции.
Вот пример:

Получение значения Radio Button (Избранная Radio Button)

Чтобы получить текущую выбранную radio кнопку или ее значение, вы можете передать параметр переменной и получить его значение.

Обучение Python GUI (уроки по Tkinter)

Каждый раз, когда вы выбираете radio button, значение переменной будет изменено на значение кнопки.

Добавление виджета ScrolledText (текстовая область Tkinter)

Чтобы добавить виджет ScrolledText , используйте класс ScrolledText :

Здесь нужно указать ширину и высоту ScrolledText , иначе он заполнит все окно.

Обучение Python GUI (уроки по Tkinter)

Результат:

Настройка содержимого Scrolledtext

Используйте метод insert , чтобы настроить содержимое Scrolledtext :

Удаление/Очистка содержимого Scrolledtext

Чтобы очистить содержимое данного виджета, используйте метод delete :

Чтобы показать всплывающее окно с помощью Tkinter, используйте messagebox следующим образом:

Обучение Python GUI (уроки по Tkinter)

Когда вы нажмете на кнопку, появится информационное окно.

Показ диалоговых окон с выбором варианта

Если вы кликнете OK, yes или retry, значение станет True, а если выберете no или cancel, значение будет False.
Единственной функцией, которая возвращает одно из трех значений, является функция askyesnocancel ; она возвращает True/False/None.

Добавление SpinBox (Виджет спинбокс)

Для создания виджета спинбокса, используйте класс Spinbox :

Таким образом, мы создаем виджет Spinbox , и передаем параметры from и to , чтобы указать диапазон номеров.
Кроме того, вы можете указать ширину виджета с помощью параметра width :

Проверим пример полностью:

Обучение Python GUI (уроки по Tkinter)

Вы можете указать числа для Spinbox , вместо использования всего диапазона следующим образом:

Виджет покажет только эти 3 числа: 3, 8 и 11.

Задать значение по умолчанию для Spinbox

В случае, если вам нужно задать значение по умолчанию для Spinbox, вы можете передать значение параметру textvariable следующим образом:

Теперь, если вы запустите программу, она покажет 36 как значение по умолчанию для Spinbox.

Добавление виджета Progressbar

Чтобы создать данный виджет, используйте класс progressbar :

Установите значение progressbar таким образом:

Вы можете установить это значение на основе любого процесса или при выполнении задачи.

Изменение цвета Progressbar

Изменение цвета Progressbar немного сложно. Сначала нужно создать стиль и задать цвет фона, а затем настроить созданный стиль на Progressbar. Посмотрите следующий пример:

Обучение Python GUI (уроки по Tkinter)

И в результате вы получите следующее:

Добавление поля загрузки файла

Для добавления поля с файлом, используйте класс filedialog :

После того, как вы выберете файл, нажмите “Открыть”; переменная файла будет содержать этот путь к файлу. Кроме того, вы можете запросить несколько файлов:

Указание типа файлов (расширение фильтра файлов)

Возможность указания типа файлов доступна при использовании параметра filetypes , однако при этом важно указать расширение в tuples.

Вы можете запросить каталог, используя метод askdirectory :

Вы можете указать начальную директорию для диалогового окна файла, указав initialdir следующим образом:

Добавление панели меню

Для добавления панели меню, используйте класс menu :

Сначала мы создаем меню, затем добавляем наш первый пункт подменю. Вы можете добавлять пункты меню в любое меню с помощью функции add_cascade() таким образом:

Наш код будет выглядеть так:

Обучение Python GUI (уроки по Tkinter)

Таким образом, вы можете добавить столько пунктов меню, сколько захотите.

Обучение Python GUI (уроки по Tkinter)

Теперь мы добавляем еще один пункт меню “Изменить” с разделителем меню. Вы можете заметить пунктирную линию в начале, если вы нажмете на эту строку, она отобразит пункты меню в небольшом отдельном окне.

Можно отключить эту функцию, с помощью tearoff подобным образом:

Просто отредактируйте new_item , как в приведенном выше примере и он больше не будет отображать пунктирную линию.
Вы так же можете ввести любой код, который работает, при нажатии пользователем на любой элемент меню, задавая свойство команды.

Добавление виджета Notebook (Управление вкладкой)

Для удобного управления вкладками реализуйте следующее:

  • Для начала, создается элемент управления вкладкой, с помощью класса Notebook .
  • Создайте вкладку, используя класс Frame .
  • Добавьте эту вкладку в элемент управления вкладками.
  • Запакуйте элемент управления вкладкой, чтобы он стал видимым в окне.

Обучение Python GUI (уроки по Tkinter)

Таким образом, вы можете добавлять столько вкладок, сколько нужно.

Добавление виджетов на вкладку

После создания вкладок вы можете поместить виджеты внутри этих вкладок, назначив родительское свойство нужной вкладке.

Обучение Python GUI (уроки по Tkinter)

Добавление интервала для виджетов (Заполнение)

Вы можете добавить отступы для элементов управления, чтобы они выглядели хорошо организованными с использованием свойств padx и pady .

Передайте padx и pady любому виджету и задайте значение.

Это очень просто!

В этом уроке мы увидели много примеров GUI Python с использованием библиотеки Tkinter. Так же рассмотрели основные аспекты разработки графического интерфейса Python. Не стоит на этом останавливаться. Нет учебника или книги, которая может охватывать все детали. Надеюсь, эти примеры были полезными для вас.

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

2 ответа

Вы можете попробовать все то, что предложил @abarnert, но я думаю, что самый простой способ - просто игнорировать событие close.

(отредактированный код для Windows)

Поэтому измените on_closing() на
def on_closing (): передать
и это делает его не подлежащим закрытию. Я пробовал Alt + F4 , кнопку закрытия, закрывая ее с панели задач Windows, но все безрезультатно. Единственный способ убить его - использовать диспетчер задач.

У Tkinter нет никакого способа сделать это напрямую. Но у него есть кое-что, что может быть достаточно хорошим, или это может быть слишком излишним: overrideredirect :

Если не ноль, это препятствует тому, чтобы оконный менеджер украсил окно. Другими словами, окно не будет иметь заголовка или границы, и его нельзя будет перемещать или закрывать обычными средствами.

Это не совсем актуально; на некоторых платформах он может иметь заголовок или границу . но он не будет закрываемым.

Это легко использовать: просто сделайте root.overrideredirect(True) (или, если вы хотите сделать это в другом окне Toplevel вместо своего корня, window.overrideredirect(True) ).

Но обратите внимание, что его нельзя переместить или закрыть , а не только то, что его нельзя закрыть. (Его также нельзя изменить, если вы этого хотите.)

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

Очевидно, что если вы хотите, чтобы какие-либо виджеты в окне принимали щелчки, вы, вероятно, не хотите превращать все окно в область перетаскивания. На самом деле, вы можете не захотеть превращать все окно в область перетаскивания, даже если на нем нечего щелкать, потому что на самом деле это не соответствует принципам интерфейса пользователя для Mac или Windows. Вы можете подделать область захвата - строку заголовка, рамку вокруг окна и т. Д. - просто добавив Label , прикрепленный к той стороне (сторонам), с которой хотите захватить, и только > или путем создания вставки «дочернего» окна из главного окна, которая крадет bind . Но это никогда не будет выглядеть как «родное» окно.

Если вам действительно нужно собственное окно, но с отключенным или отсутствующим окном закрытия ( X в верхнем правом углу в Windows, красная точка в верхнем левом углу на Mac и т. Д.) (И, на Windows с отключенным пунктом «Закрыть» в меню окна, Alt + F4 и т. Д., И аналогично для X11…)… Насколько я знаю, в Tkinter нет кроссплатформенного способа сделать это. Вам нужно будет написать код для каждой платформы, который получает базовые объекты собственного окна и выполняет с ними какие-либо действия. В этот момент вы, вероятно, захотите использовать более мощную библиотеку окон, чем Tkinter - например, я считаю, что у Qt, Gtk + и wx есть гораздо более простые способы создания нормального окна, но с отключенным окном закрытия.

I wish to make stand-alone binaries for Linux and Windows of it. And mainly I wish that when the bot initiates, the console window should hide and the user should not be able to see the window.

What can I do for that?

9 Answers 9

Simply save it with a .pyw extension. This will prevent the console window from opening.

On Windows systems, there is no notion of an “executable mode”. The Python installer automatically associates .py files with python.exe so that a double-click on a Python file will run it as a script. The extension can also be .pyw, in that case, the console window that normally appears is suppressed.

In linux, just run it, no problem. In Windows, you want to use the pythonw executable.

Update

Okay, if I understand the question in the comments, you're asking how to make the command window in which you've started the bot from the command line go away afterwards?

I think that's right. In any case, now you can close the terminal.

Thats not the main issue . The main issue is to hide the console window then the program is running. How do it do that ?

"nohup mypythonprog &" will help me in linux . but python is not gonna be installed on the windows machine. So "start pythonw mypythonprog" wont help me i guess.

On Unix Systems (including GNU/Linux, macOS, and BSD)

Use nohup mypythonprog & , and you can close the terminal window without disrupting the process. You can also run exit if you are running in the cloud and don't want to leave a hanging shell process.

On Windows Systems

Save the program with a .pyw extension and now it will open with pythonw.exe . No shell window.

For example, if you have foo.py , you need to rename it to foo.pyw .

This will hide your console. Implement these lines in your code first to start hiding your console at first.

Update May 2020 :

If you've got trouble on pip install win32con on Command Prompt, you can simply pip install pywin32 .Then on your python script, execute import win32.lib.win32con as win32con instead of import win32con .

To show back your program again win32con.SW_SHOW works fine:

Please explain your code in English. Thanks! Someone who doesn't need an explanation could have written it themselves.

to show the hided program again use this line: win32gui.ShowWindow(The_program_to_hide , win32con.SW_SHOW)

If all you want to do is run your Python Script on a windows computer that has the Python Interpreter installed, converting the extension of your saved script from '.py' to '.pyw' should do the trick.

But if you're using py2exe to convert your script into a standalone application that would run on any windows machine, you will need to make the following changes to your 'setup.py' file.

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

1 contributor

Users who have contributed to this file

  • Open with Desktop
  • View raw
  • Copy raw contents Copy raw contents

Copy raw contents

Copy raw contents

Наверное самый лучший способ работы с предлагаемым материалом - изучать код, запускать его на компьютере и затем снова анализировать код. В комментариях разъясняется каждый новый фрагмент кода по мере его расширения. Полный работающий модуль находится в корневой директории. Для просмотра кода перейдите по ссылке, указанных ниже, в данном руководстве.

Первый модуль Python window_01.py создает пустое окно 200x150 с названием "myWindow", расположенное в центре экрана.

Данная строка загружает в Python весь модуль Tkinter целиком. В результате у Python появляется библиотека для построения оконного интерфейса.

Tk() - это функция Tkinter, открывающая главное окно любого приложения. Здесь мы создаем экземпляр с именем root. Это общая черта всех классов Tkinter - они должны быть присвоены какой-либо переменной. В следующих двух командах задаются некоторые свойства root, определяющие заголовок и размеры окна. Это другой общий факт - взаимодействие с объектами Tkinter происходит через задание свойств [и вызов методов]. '200x150+300+225' означает [ширина x высота + координата_x_верхнего_левого_угла + координата_y_верхнего_левого_угла].

Наконец, в этой строке происходит вызов метода Tk() под названием mainloop(), который держит окно раскрытым, пока оно не будет закрыто нажатием кнопки [x] на окне или вызовом метода Tk() destroy().

Довольно просто, не так ли? Понадобилось всего шесть строчек кода. Запустите Python; загрузите модуль Tkinter; присвойте какой-либо переменной значение Tk(); затем настройте три метода Tk() для этой переменной. Итак, запускаем window_01.py. Voila! Вы создали окно - фундаментальный элемент любого графического интерфейса пользователя Tkinter.

Создание "дочернего" окна

Следующий модуль Python - window_02.py помещает на экран еще одно пустое "дочернее" окно 200x150. В большинстве графических интерфейсов для организации диалога используют всплывающие окна. "Дочернее" окно исчезает при закрытии основного окна.

Toplevel() - это класс Tkinter, с помощью которого можно создавать любое окно кроме главного. Он также присваивается переменной child. Toplevel(root) означает дочернее окно child, относящееся и зависящее от родительского окна root. Следующие две команды формируют заголовок и размеры дочернего окна аналогично случаю родительского окна. Коду дочернего окна не нужен свой метод mainloop(). Он запускается из родительского окна.

Снова довольно просто. Потребовалось лишь три дополнительные строчки кода. Присвойте Toplevel() новой переменной; свяжите его с корневым окном root с помощью Toplevel(root); затем задайте значения пары свойств Toplevel(root). Наконец, запустите window_02.py. Мы движемся быстро. Мы умеем создавать родительское окно и любое число дочерних окон. Закрытие родительского окна вызывает закрытие и окна дочернего, но не наоборот.

Уже похоже на интерфейс.

Работа с классами

Python - это объектно-ориентированный язык программирования. Tk() и Toplevel() являются классами Tkinter, принимающими форму объектов для создания на экране графических окон. Программирование на Tkinter подразумевает комбинирование и преобразование встроенных классов Tkinter в новые классы с индивидуальными свойствами и методами.

Следующей задачей данного руководства будет воспроизведение визуального эффекта, достигнутого в последнем примере window_02.py, объектно-ориентированными средствами, заложенными в Python, т.е. путем создания классов. Приведенный выше код объявляет и определяет класс. Объект - это экземпляр класса. В данном случае мы собираемся создать простые классы родительских и дочерних окон. Позже мы будем формировать классы с их собственными (добавленными) свойствами и методами. Модуль, который рассматривается в этой части руководства, находится по ссылке window_03.py.

Вот обобщенная форма для создания классов. Замечание: отступы обязательны!

Здесь указывается, что будет создан класс с именем имя-класса со следующими определениями [def]. Команду __init__(self) проще показать в действии, чем объяснить. __init__() - это конструктор объектов, позволяющий создавать экземпляр объекта во время исполнения программы. self - это метка экземпляра, необходимая для привязки переменных класса к данному объекту. Таким образом инструкция self.master = root создает переменную master и присваивает ей глобальное значение root [пока еще не определенное]. В оставшейся части кода вы увидите, как теперь определяется то же самое окно внутри класса main. Итак, что же такое child()?

child() - это вызов другого класса, определенного в модуле. Так класс main генерирует экземпляр дочернего окна.

При запуске модуля на выполнение происходит вызов Python, загрузка Tkinter и сохранение определений классов main и child. Команды, приведенные выше, сначала задают значение переменной root, чтобы создать экземпляр Tk(), затем открывают окно, активируя main [который, в свою очередь, активирует child]. Обратите внимание, что mainloop() расположен "внутри" класса main. Запустите window_03.py. Он должен сделать то же самое, что и предыдущий пример.

Если этот пример - ваша первая встреча с классами, объектами и т.п., в голову вполне может прийти мысль: "К чему такие сложности?" Но стоит нам перейти к более сложным примерам, как тотчас станет очевидно, что инкапсуляция кода внутрь классов - это отличный способ писать лаконичные, пригодные для многократного использования программы на Python. Потерпите немного. Некоторые из нас помнят, как учились составлять "макаронные" программы ['spaghetti' coding - слабо структурированные программы с большим размером процедур и интенсивным использованием оператора goto; трудны для изучения и модификаций], а потом изучали "структурное" программирование. Так что "объектно-ориентированное" программирование - это еще одна новинка.

Классы и элементы управления

Запустите следующий модуль, что б ознакомится с элементами управления window_04.py.

Оставим на время разработку дочернего окна, чтобы сосредоточить все внимание на классах. Рассмотрим, как передавать классу информацию, и добавим к классу элемент управления [в данном случае кнопку (Button)], [и объект и окно].

В последнем примере window_03.py вас, возможно, удивило, что класс main содержит ссылку на переменную root, которая в программе еще не создана. Я сделал это специально, чтобы продемонстрировать, что классы ничего не делают, пока на их базе не будут созданы экземпляры объектов. Но есть лучший путь достичь того же самого. Объекту можно передать глобальную переменную root, и именно так сделано в нашем коде. Благодаря вызову main(root) параметр root передается переменной master класса main. В последующих примерах подобным же образом мы будем передавать классам множество различных параметров.

Ну, наконец и элемент управления. В Tkinter имеется определенное число графических элементов управления, которые можно размещать в нашем окне. В данном случае это будет кнопка (Button). Мы уже пользовались двумя элементами управления - Tk() и Toplevel(). Код self.button = Button(self.master, text = 'myButton') связывает элемент управления Button() с классом main [все элементы управления кроме Tk() кому-нибудь "принадлежат"], а text = 'myButton' задает значение свойства text [текст, который отобразится на кнопке во время исполнения программы]. Строка self.button.pack(side = BOTTOM) определяет, в какой части окна появится наша кнопка. Позже мы рассмотрим pack подробнее.

Между прочим, эта кнопка пока ничего не делает. Итак, запускаем window_04.py и нажимаем бесполезную кнопку.

Любая кнопка должна что-нибудь делать. В данном случае мы свяжем событие "нажатие кнопки" с открытием дочернего окна из одного из прошлых примеров. Для этого в класс main вводится метод openDialog, который создает экземпляр объекта child.

Для определения метода openDialog не нужна функция __init__(). Не создается экземпляра метода, - но метод создает экземпляр объекта child. Метод - это то, что класс main делает, а не то, чем класс main является.

Обращение к openDialog содержит вездесущее self. Это означает, что метод openDialog является внутренним по отношению к main.

Toplevel() из класса child узнает о том, что относится к дочернему классу класса main, довольно мучительным путем. Tk(), связанный с root, передается классу main через параметр master [в main], а затем пересылается другому параметру master [в child]. Всякий класс имеет свою переменную master, локальную по отношению к данному классу. Их имена могут быть различными. Ага! Метод. Запускаем window_05.py и испытываем работающую кнопку.

Модальное дочернее окно

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

child перехватывает все события, происходящие в приложении.

child захватывает фокус.

child ждет, когда будет уничтожен текущий объект, не возобновляя работы [но и не оказывая влияния на основной цикл].

Итак, рецепт. Если нужно создать модальное окно, воспользуйтесь этими тремя методами. Как говорится, "Просто сделай это!" window_06.py

Модальные дочерние окна используются, главным образом, в роли диалоговых окон. Нам нужен способ передачи информации от родительского окна к дочернему и наоборот. Сперва пойдем от main к child. В данный пример внесено три добавления по сравнению с предыдущими: Поле для ввода текста в классе main. Текстовое окно в классе child для отображения введенной информации. Механизм передачи информации от текстового окна в main текстовому окну в child.

Стоит создать один элемент управления, как все остальное становится ясно. Единственно стоит отметить, что элемент управления text имеет свойство background (фон) со значением 'white' (белый) и что пришло время поговорить о pack. Метод pack() размещает в окне элемент управления. Итак: side (сторона) определяет, какой стороны окна будет "держаться" элемент управления варианты: TOP (сверху) RIGHT (справа) LEFT (слева) BOTTOM (снизу) по умолчанию: NONE (никак) fill (заполнение) показывает, заполнит элемент доступное пространство или нет. варианты: X Y BOTH (X Y оба) по умолчанию: NONE (никак) expand (растяжение) указывает, будет ли элемент управления менять свой размер при изменении размеров окна. варианты: YES (да) по умолчанию: 0

В метод openDialog() мы ввели инструкцию self.text.get('0.0', END), которая является методом элемента управления Text. Она собирает все содержимое текстового окна от строки 0 символа 0 и до конца, чтобы передать его классу/окну child [как myText].

Как работает текстовый элемент управления child интуитивно ясно. Он заполняется текстом из главного окна посредством def __init__(self, master, myText = ''). Информация из myText вставляется в элемент управления text с помощью метода self.text.insert('0.0', myText), который помещает ее, начиная со строки 0 символа 0. Испытайте window_07.py, напечатав в нем какой-нибудь текст и отослав его.

Общение - хорошая штука, но оно должно быть улицей с двухсторонним движением.

Сначала посмотрите на код window_08.py.

Мы хотим, чтобы информация шла от родительского окна к дочернему И от дочернего к родительскому. Последнего можно добиться, добавив к дочернему окну кнопку accept и метод для регистрации всех изменений, произведенных в передаваемом тексте; также введем метод go как для создания экземпляра дочернего окна, так и для управления процессом обмена информацией. Такое применение методов [go] для открытия дочерних окон - полезный инстру. мент, который приобретет особую важность, когда мы будем иметь дело с более сложными операциями в последующих руководствах. Сейчас же он создает пустую переменную newValue, в которую будет записан измененный текст [если он был изменен].

При вызове дочернего метода go введенный текст вставляется в дочернее текстовое окно. Если текст редактировался и пользователь нажимает кнопку accept, исправленный текст возвращается как newValue. Если дочернее окно просто закрывается, newValue возвращается с пустым значением.

При возврате метод openDialog класса main осуществляет проверку. Если возвращаемая строка не пустая, возвращаемый текст будет вставлен в текстовое окно main.

Запускаем window_08.py. Убедитесь, что вы "уловили", как работает go. Нам придется еще довольно много иметь дело с этим методом.

Мы приближаемся к концу начала. Рассмотрим еще несколько приемов, которые будут использоваться позднее в "реальном" приложении: кнопки принятия (accept) и отмены (cancel), а также "перехват" закрытия основного окна с соответствующим диалогом.

Пока все просто. Размещение в дочерних диалоговых окнах кнопки отмены (cancel) - довольно стандартный прием. При этом происходит уничтожение дочернего окна без изменения newValue.

"Перехват" закрытия пользователем главного окна немного сложнее. Для чего это может потребоваться? Допустим, в случае текстового редактора нам бы хотелось фиксировать ситуации, когда не был сохранен измененный файл, чтобы предохранить пользователя от нечаянного уничтожения плодов всех его усилий из-за преждевременного закрытия окна.

Запустите window_09.py, чтобы увидеть нашу программу в действии.

Наша программа растет. У нас получается. И что еще более важно, ее части возможно использовать повторно. Класс yesno может быть применен еще раз в этом же приложении или даже в будущих приложениях. Итак, в коде, приводимом ниже, мы разбиваем программу на три отдельных модуля, которые будут храниться в трех отдельных автономных файлах. Основной файл myWindow.py использует классы dialog и yesno так же, как и раньше, но, вместо того чтобы включить их в код, они импортируются из других файлов - myDialog.py и myBoolean.py.

Просмотрите завершающие части файлов myDialog.py и myBoolean.py. Там есть тестовая команда. Включать подобную команду в конец любого файла, который не выполняется напрямую, - стандартное правило. С помощью оператора if __name__ == '__main__': она проверяет, запущен файл из другой программы или сам по себе. В последнем случае открывается пустое окно, которое затем убирается с экрана командой root.withdraw(). Но именно к этому фиктивному окну привязывается рабочий код, позволяющий запускать данный файл. Это очень полезный инструмент для отладки. Использование тестов приводит к тому, что все модули становятся "исполняемыми".

Итак, запустим все три файла - myWindow.py, myDialog.py, myBoolean.py - и посмотрим, что произойдет.

Мини-руководство по Tkinter

Программа, которую мы составили, не сильно впечатляет - что-то вроде импровизации на тему "Hello World!". Предыдущая страница была названа "святым граалем" по двум причинам. Прежде всего, Python никак не связан со змеей. Это название взято из известного сериала Monty Python and the Quest for the Holy Grail. Кроме того, в легенде о Граале рассказывается о том, как нечто искали повсюду, и, когда, наконец, оно было найдено, оказалось, что ищущий обладал им с самого начала. Это учебное руководство было написано пять или шесть лет тому назад. Тогда оно не было опубликовано, поскольку я посчитал его слишком примитивным. Позднее это руководство выручило меня самого, облегчив вспоминание Tkinter. Сейчас я сознаю, что оно уже содержало все необходимые идеи, чтобы начать использовать Tkinter для интересующих меня задач. Если вы похожи на меня, то будете применять Python для написания различных утилит, которые часто бывают полезны в повседневной жизни. Это превосходный язык для таких целей [а Tkinter - почти совершенный GUI]. Но для создания коммерческих мегапрограмм, чтобы заработать много денег, ни Python, ни Tkinter не годятся. [Как, впрочем, и само программирование в целом. Лучше идите учиться на менеджера!].

Перечислим элементы управления, с которыми мы уже успели познакомиться, вместе с их свойствами и методами, использованными в примерах. Общий стиль Tkinter - это размещение свойств внутри круглых скобок: Имя_класса(свойство1 = значение1, свойство2 = значение2) и использование методов в роли особых "точечных" команд: Имя_класса.метод(параметры)

Класс Свойства Методы
Tk()
Toplevel() parent title(string); geometry(string); mainloop(); destroy()
Button() parent; text = string; command = method pack(side)
Text() parent pack(side, fill, expand); insert(index, string); get(index1, index2); delete(index1, index2)
Label() parent configure(text = string); pack(side, fill, expand)
Frame() parent pack(side, fill)

Мы уже извлекли из этой демонстрационной программы всю пользу, какую только можно было. Настало время заняться созданием "настоящей программы" [более крупного "Hello World!] - на этот раз - текстового редактора. В ходе работы мы повстречаемся с новыми элементами управления: линейками прокрутки, линейками меню и кнопками меню, выпадающими списками, кнопками-флажками и т.п. Приятный сюрприз: за исключением пары ухищрений вы уже умеете пользоваться ими. Цель нового проекта - разработка работающего текстового редактора [если хотите его испытать, запустите editor.py]. Это учебное руководство посвящено только Tkinter, а не всему Python. Таким образом, хотя в предлагаемом вашему вниманию коде будут программные функции, реализованные на Python, обсуждение будет сфокусировано преимущественно на интерфейсе Tkinter. И снова вы будете удивлены. Даже если вы никогда раньше не работали с Python, подавляющая часть кода будет понятной.

Я хочу сделать из него автономные двоичные файлы для Linux и Windows. И в основном я хочу, чтобы при запуске бота окно консоли скрывалось, и пользователь не мог видеть это окно.

Что я могу для этого сделать?

Просто сохраните его с .pyw расширением. Это предотвратит открытие окна консоли.

On Windows systems, there is no notion of an “executable mode”. The Python installer automatically associates .py files with python.exe so that a double-click on a Python file will run it as a script. The extension can also be .pyw, in that case, the console window that normally appears is suppressed.

В linux просто запустите, без проблем. В Windows вы хотите использовать исполняемый файл pythonw.

Обновлять

Хорошо, если я понимаю вопрос в комментариях, вы спрашиваете, как впоследствии закрыть командное окно, в котором вы запустили бота из командной строки?

Я думаю , что это правильно. В любом случае теперь вы можете закрыть терминал.


Это не основная проблема . Основная проблема заключается в том, чтобы скрыть окно консоли, когда программа работает. Как это сделать?

"nohup mypythonprog &" поможет мне в Linux . но python не будет установлен на машине Windows. Так что "start pythonw mypythonprog" мне не поможет.

В системах Unix (включая GNU / Linux, macOS и BSD)

Используйте nohup mypythonprog & , и вы можете закрыть окно терминала, не прерывая процесс. Вы также можете запустить, exit если вы работаете в облаке и не хотите оставлять зависший процесс оболочки.

В системах Windows

Сохраните программу с .pyw расширением, и теперь она откроется с расширением pythonw.exe . Нет окна оболочки.

Например, если у вас есть foo.py , вам нужно переименовать его в foo.pyw .


Это скроет вашу консоль. Сначала внедрите эти строки в свой код, чтобы сначала начать скрывать консоль.

Обновление за май 2020 г .:

Если у вас возникли проблемы с pip install win32con командной pip install pywin32 строкой , вы можете просто. Затем в своем скрипте python выполнить import win32.lib.win32con as win32con вместо import win32con .

Чтобы снова показать вашу программу, все win32con.SW_SHOW работает нормально:


Пожалуйста, объясните свой код на английском языке. Спасибо! Кто-то, кому объяснения не нужны, мог бы написать это сам.

чтобы снова показать скрытую программу, используйте эту строку: win32gui.ShowWindow (The_program_to_hide, win32con.SW_SHOW)

Если все, что вам нужно сделать, это запустить свой скрипт Python на компьютере под управлением Windows, на котором установлен Python Interpreter, преобразование расширения вашего сохраненного скрипта из «.py» в «.pyw» должно помочь.

Но если вы используете py2exe для преобразования вашего скрипта в отдельное приложение, которое будет работать на любом компьютере с Windows, вам нужно будет внести следующие изменения в ваш файл «setup.py».

Следующий пример представляет собой простой графический интерфейс Python, созданный с использованием Tkinter:

Измените "console" в приведенном выше коде на "windows".

Это откроет только графический интерфейс, созданный Tkinter, но не окно консоли.

Хотя мне кажется, что этот ответ немного не по теме вопроса, я все равно разместил его, поскольку он отвечает на следующий вопрос (ссылка ниже), который был помечен как дубликат этого вопроса.

Читайте также: