Pyinstaller сразу окно закрывается pygame

Обновлено: 13.05.2024

Pygame задает особые правила построения кода. Эти правила не являются строгими. Однако в большинстве случаев, чтобы игра благополучно запустилась, в программе должна быть соблюдена определенная последовательность вызова ключевых команд.

Эти команды (импорт модуля, вызовы функций, цикл) создают своего рода скелет, или каркас, программного кода. Выполнив его, вы получите "пустую" игру. Далее на этот скелет "подвешивается мясо", т. е. объявляются объекты и программируется логика игры.

Первое, что нужно сделать, это импортировать модуль pygame. После этого можно вывести на экран главное графическое окно игры с помощью функции set_mode() модуля display, входящего в состав библиотеки pygame:

Если выполнить этот код, то появится окно размером 600x400 пикселей и сразу закроется (в Linux, в Windows может зависнуть).

Функция set_mode() принимает три аргумента – размер в виде кортежа из двух целых чисел, флаги и глубину цвета. Их можно не указывать. В этом случае окно займет весь экран, цветовая глубина будет соответствовать системной. Обычно указывают только первый аргумент – размер окна.

Флаги предназначены для переключения на аппаратное ускорение, полноэкранный режим, отключения рамки окна и др. Например, команда pygame. display . set_mode ( ( 640 , 560 ) , pygame. RESIZABLE ) делает окно изменяемым в размерах.

Выражение вида pygame.RESIZABLE (вместо RESIZABLE может быть любое другое слово большими буквами) обозначает обращение к той или иной константе, определенной в модуле pygame. Часто можно встретить код, в котором перед константами не пишется имя модуля (вместо, например, pygame.QUIT пишут просто QUIT). В этом случае в начале программы надо импортировать не только pygame, но и содержимое модуля locals через from … import:

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

Функция set_mode() возвращает объект типа Surface (поверхность). В программе может быть множество объектов данного класса, но тот, что возвращает set_mode() особенный. Его называют display surface, что можно перевести как экранная (дисплейная) поверхность. Она главная.

В конечном итоге все отображается на ней с помощью функции pygame.display.update() или родственной pygame.display.flip(), и именно эту поверхность мы видим на экране монитора. Нам пока нечего отображать, мы не создавали никаких объектов. Поэтому было показано черное окно.

Функции update() и flip() модуля display обновляют содержимое окна игры. Это значит, что каждому пикселю заново устанавливается цвет. Представьте, что на зеленом фоне движется красный круг. За один кадр круг смещается на 5 пикселей. От кадра к кадру картинка целого окна изменяется незначительно, но в памяти окно будет перерисовываться полностью. Если частота составляет 60 кадров в секунду (FPS=60), то за секунду в памяти компьютера произойдет 60 обновлений множества значений, соответствующих экранным пикселям, что дает по большей части бессмысленную нагрузку на вычислительные мощности.

Если функции update() не передавать аргументы, то будут обновляться значения всей поверхности окна. Однако можно передать более мелкую прямоугольную область или список таковых. В этом случае обновляться будут только они.

Функция flip() решает проблему иным способом. Она дает выигрыш, если в set_mod() были переданы определенные флаги (аппаратное ускорение + полноэкранный режим – pygame.HWSERFACE|pygame.FULLSCREEN, двойная буферизация – pygame.DOUBLEBUFF, использование OpenGL – pygame.OPENGL). Возможно, все флаги можно комбинировать вместе (через |). При этом, согласно документации, аппаратное ускорение работает только в полноэкранном режиме.

Вернемся к нашим трем строчкам кода. Почему окно сразу закрывается? Очевидно потому, что программа заканчивается после выполнения этих выражений. Ни init(), ни set_mode() не предполагают входа в "режим циклического ожидания событий". В tkinter для этого используется метод mainloop() экземпляра Tk(). В pygame же требуется собственноручно создать бесконечный цикл, заставляющий программу зависнуть. Основная причина в том, что только программист знает, какая часть его кода должна циклически обрабатываться, а какая – нет. Например, код, создающий классы, объекты и функции не "кладут" в цикл.

Итак, создадим в программе бесконечный цикл:

После такого окно уже не закроется, а программа благополучно зависнет насовсем. Многократные клики по крестику не помогут. Только принудительная остановка программы через среду разработки или Ctrl+С, если запускали через терминал.

Как сделать так, чтобы программа закрывалась при клике на крестик окна, а также при нажатии Alt+F4? Pygame должен воспринимать такие действия как определенный тип событий.

Добавим в цикл магии:

При выходе будет генерироваться ошибка, пока забудем про нее. Сейчас достаточно того, что окно успешно закрывается.

Рассмотрим выражение pygame.event.get(). Модуль event библиотеки pygame содержит функцию get(), которая забирает список событий из очереди, в которую записываются все произошедшие события. То, что возвращает get() – это список. Забранные события удаляются из очереди, то есть второй раз они уже забираться не будут, а в очередь продолжают записываться новые события.

Цикл for просто перебирает схваченный на данный момент (в текущей итерации цикла) список событий. Каждое событие он присваивает переменной i или любой другой. Чтобы было понятней, перепишем программу таким образом:

На экране вы увидите примерно такое:

Вверху будет множество пустых квадратных скобок, которые соответствуют пустым спискам events, создаваемым на каждой итерации цикла while. И только когда окно закрывается, генерируются два события. Свойство type второго имеет значение 256, что совпадает со значением константы QUIT.

В pygame событие – это объект класса Event. А если это объект, то у него есть атрибуты (свойства и методы). В данном случае мы отслеживаем только те события, у которых значение свойства type совпадает со значением константы QUIT модуля pygame. Это значение присваивается type тогда, когда происходят события нажатия на крестик или Alt+F4. Когда эти события происходят, то в данном случае мы хотим, чтобы выполнилась функция quit() модуля pygame, которая завершает его работу.

Теперь почему возникает ошибка. Функция pygame.quit() отключает (деинициализирует) pygame, но не завершает работу программы. Таким образом, после выполнения этой функции отключаются модули библиотеки pygame, но выхода из цикла и программы не происходит. Программа продолжает работу и переходит к следующей итерации цикла while (или продолжает выполнять тело данной итерации, если оно еще не закончилось).

В данном случае происходит переход к следующей итерации цикла while. И здесь выполнить функцию get() модуля event оказывается уже невозможным. Возникает исключение и программа завершается. По-сути программу завершает не функция pygame.quit(), а выброшенное, но не обработанное, исключение.

Данную проблему можно решить разными способами. Часто используют функцию exit() модуля sys. В этом случае код выглядит примерно так:

Сначала отключается pygame, потом происходит выход из программы. Такой вариант вероятно следует считать наиболее безопасным завершением. Команда pygame.quit() не обязательна. Если завершается программа, то отключится и pygame.

Другой вариант – не допустить следующей итерации цикла. Для этого потребуется дополнительная переменная:

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

Нередко код основной ветки программы помещают в функцию, например, main(). Она выполняется, если файл запускается как скрипт, а не импортируется как модуль. В этом случае для завершения программы проще использовать оператор return, который осуществляет выход из функции.

Теперь зададимся вопросом, с какой скоростью крутится цикл while? С большой, зависящей от мощности компьютера. Но в данном случае такая скорость не есть необходимость, она даже вредна, так как бессмысленно расходует ресурсы. Человек дает команды и воспринимает изменения куда медленнее.

Для обновления экрана в динамической игре часто используют 60 кадров в секунду, а в статической, типа пазла, достаточно будет 30-ти. Из этого следует, что циклу незачем работать быстрее.

Поэтому в главном цикле следует выполнять задержку. Делают это либо вызовом функции delay() модуля time библиотеки pygame, либо создают объект часов и устанавливают ему частоту кадров. Первый способ проще, второй – более профессиональный.

Функция delay() принимает количество миллисекунд (1000 мс = 1 с). Если передано значение 20, то за секунду экран обновится 50 раз. Другими словами, частота составит 50 кадров в секунду.

Методу tick() класса Clock передается непосредственно желаемое количество кадров в секунду. Задержку он вычисляет сам. То есть если внутри цикла указано tick(60) – это не значит, что задержка будет 60 миллисекунд или произойдет 60 обновлений экрана за одну итерацию цикла. Это значит, что на каждой итерации цикла секунда делится на 60 и уже на вычисленную величину выполняется задержка.

Нередко частоту кадров выносят в отдельную константоподобную переменную:

В итоге каркас игры на Pygame должен выглядеть примерно так:

Практическая работа

В модуле pygame.display есть функция set_caption(). Ей передается строка, которую она устанавливает в качестве заголовка окна. Сделайте так, чтобы каждую секунду заголовок окна изменялся.

Курс с примерами решений практических работ:
android-приложение, pdf-версия

Когда я пытаюсь запустить этот код pygame, он мгновенно закрывается ??

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

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


Откуда у вас функция interpret() ? vanishingtext никогда не инициализируется. Кажется, что ваши последние два утверждения имеют неправильный уровень отступа.

Я исправил те сейчас, я стер interpret() и vanishingtext и фиксированные отступы. это все еще не работает.

Код не звонит pygame.init() . Также есть два цикла событий, второй из которых просто пропадет, как только running станет False .

Этот код дает мне окно с названием «толстое» с белым фоном. Печатая на английской клавиатуре, я получаю синие буквы, которые можно вернуть назад. Нажатие Enter несколько обработано.

Я попытался объединить циклы while. while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: text += event.unicode elif event.type == pygame.K_BACKSPACE: text = text[:-1] elif event.type == pygame.K_RETURN: text = "" else: pass Окно по-прежнему работает, но если вы знаете, что не так, не могли бы вы помочь? Я пытаюсь сделать так, чтобы все, что я набираю, появлялось на моем экране. Не работает, есть идеи, почему бы и нет? В моем комментарии не работает отступ, извините!

В нем прямо говорится, что нельзя благодарить, но я просто скажу большое спасибо. Я только начал заниматься питоном и очень благодарен за помощь. Удачного тебе дня.

Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нем неправильно.
Необходимо обновить браузер или попробовать использовать другой.

Валентин

Новичок

после компиляции, когда открываешь ЕХЕшник, он запускается и сразу закрывается. Незнаю что сделать чтобы он работал.

regnor

Модератор

не хватает библиотек скорее всего, где запускаете exe установите pyautogui через командную строку, pip install pyautogui, и все заработает.
и pyinstaller не компилирует, а упаковывает.

Валентин

Новичок

не хватает библиотек скорее всего, где запускаете exe установите pyautogui через командную строку, pip install pyautogui, и все заработает.
и pyinstaller не компилирует, а упаковывает.

VolodinAS

Новичок

Только что искал эту же проблему. Находил рекомендацию запустить Ваш exe через командную строку - выведутся все ошибки. Как у меня, например.

Валентин

Новичок

не хватает библиотек скорее всего, где запускаете exe установите pyautogui через командную строку, pip install pyautogui, и все заработает.
и pyinstaller не компилирует, а упаковывает.

Выдаёт ошибку при установке(

Валентин

Новичок

Валентин

Новичок

Только что искал эту же проблему. Находил рекомендацию запустить Ваш exe через командную строку - выведутся все ошибки. Как у меня, например. Посмотреть вложение 912

stud_55

Модератор

Валентин

Новичок

Вложения

stud_55

Модератор

Судя по логам ошибки установка у вас происходит с помощью питона 3.4, а не 3.9.
Попробуйте установить pyautogui с помощью 3.9:
выполните команду where python - она покажет где находится интерпретатор
потом выберите интерпретатор версии 3.9 (например, D:\\python39\python.exe ) и установите pyautogui с помощью него

Валентин

Новичок

Судя по логам ошибки установка у вас происходит с помощью питона 3.4, а не 3.9.
Попробуйте установить pyautogui с помощью 3.9:
выполните команду where python - она покажет где находится интерпретатор
потом выберите интерпретатор версии 3.9 (например, D:\\python39\python.exe ) и установите pyautogui с помощью него

stud_55

Модератор

После того как вы установили pyautogui для питона 3.9 нужно запустить pyinstaller из питона 3.9 чтобы сделать новый exe-файл.
После чего нужно запустить его в консоли cmd чтобы увидеть ошибки.

Валентин

Новичок

После того как вы установили pyautogui для питона 3.9 нужно запустить pyinstaller из питона 3.9 чтобы сделать новый exe-файл.
После чего нужно запустить его в консоли cmd чтобы увидеть ошибки.

Вложения

VolodinAS

Новичок

Валентин

Новичок

Если модуля нет, может быть надо его сначала установить?
В командной строке:


А лучше погуглить документацию и посмотреть. У меня Python 3.8, может не подойдет Вашей 3.9

Я конечно тупой, но не настолько. Модуль я установил. И код работает, только после сборки через pyinstaller он перестаёт работать( Но на счёт версии питона посмотрю!

VolodinAS

Новичок

Я конечно тупой, но не настолько. Модуль я установил. И код работает, только после сборки через pyinstaller он перестаёт работать(

Валентин

Новичок

Нет, хотя писало что pyautogui успешно установлен. Попробую установить питон 3.8, может действительно заработает)

VolodinAS

Новичок

Нет, хотя писало что pyautogui успешно установлен. Попробую установить питон 3.8, может действительно заработает)

Валентин

Новичок

VolodinAS

Новичок

Зайдите в настройки (Ctrl Alt S) - Project - Project Interpreter. Посмотрите внимательно на список установленных модулей.
Если запуск Вашего проекта осуществляется через PyCharm, а он говорит, что нет какой-то библиотеки, то скорее всего, проблема в виртуальной среде. У меня такая же проблема была. Она решилась выбором существующей среды во время создания проекта:

Тогда стали совпадать модули из pip list в командной строке и PyCharm:

Конечно, я еще новичок в Python и вполне вероятно, что удобно использовать отдельные виртуальные среды. Но у меня возникало куча проблем, когда я стал использовать их. Поэтому, мне проще было, чтобы всё было в одном месте.

stud_55

Модератор

Чтобы сделать рабочий exe-файл нужно чтобы pyinstaller и pyautogui были установлены для одного и того же интерпретатора питона.
Попробуйте создать виртуальное окружение для нужно интерпретатора питона.
Установите в него модули pyinstaller и pyautogui.
Запустите файл скрипта (script.py) в виртуальном окружении чтобы убедиться что он работает и все необходимые для него зависимости установлены.
Запустите pyinstaller в виртуальном окружении чтобы создать exe-файл скрипта.
Запустите exe-файл в консоли чтобы убедиться что он работает.

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

На недостаток обучалок по созданию игр на Pygame не пожалуешься, но мне не удалось найти подробной инструкции как собрать единый exe-файл, для запуска которого не требуется держать рядом папку с изображениями и игровыми звуками.

В командной строке пишем:


Создание spec-файла (файла спецификации)

Pyinstaller создает приложение, выполняя содержимое файла спецификации.

Чтобы создать spec-файл, через командную строку в папке с проектом набираем:


Флаг --onefile создает файл спецификации, который позволит упаковать всё необходимое в один exe-файл.

Получаем файл mygame.spec

Редактирование spec-файла

Теперь нужно правильно настроить spec-файл. Открываем spec-файл в текстовом редакторе.


В качестве первого атрибута для объекта класса Analysis передается имя py-файла, который нужно скомпилировать.

Атрибут pathex отвечает за путь к папке проекта.

В списке datas указываются файлы, которые нужно загрузить для работы приложения (изображения, музыка/звуки, шрифты). Datas — это список кортежей. Каждый кортеж имеет два элемента строкового типа:

  • Первый — путь до файла, который нужно загрузить.
  • Второй указывает имя папки для хранения файла во время выполнения программы
    ('.' — означает, что файл будет помещен во временную папку без подкаталога).

Редактирование путей к файлам в коде

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


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

Функция resource_path проверяет создана ли временная папка, и если да, то возвращает путь к ней для дальнейшей загрузки файлов. В противном случае (например, если запустить код через интерпретатор) функция вернет тот путь, который в неё передали (то есть путь к папке проекта с игрой).

Чтобы получить путь к файлу

  • если файл лежит в той же папке, что и py-файл, пишем:
  • если файл вынесен в отдельную папку проекта, пишем:

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

Далее загружаем файл:


С музыкой и шрифтами аналогично.

Создание exe

В командной строке вводим:


Готово! Exe-файл находится в папке dist.

Если в коде вашей игры в качестве функций выхода используются quit() или exit(), то скомпилированное приложение работать не будет.

Эти функции включены, чтобы новичкам было проще ориентироваться в коде, и предназначены только для использования в интерпретаторе. На самом деле для их корректной работы требуется загрузить модуль site.

Стандартным способом выйти из программы является использование sys.exit().

Окно не отвечает после того, как pygame создает окно, или окно pygame не может быть нормально закрыто каждый раз

Добавьте этот код после оператора цикла while

При закрытии программы нажмите кнопку закрытия окна

Таблица эффектов выглядит следующим образом:


Интеллектуальная рекомендация

Android Gausso нечеткий реализация

1, используйте скольжение Применимый сценарий: динамическая конфигурация фона изображения 2, на картину Гаусс, вам нужно передавать картинки на битовые объекты Не рекомендую: Используйте растровое изо.


Установите Spark 2.2.1 под облачным сервером Alibaba centos7.2

Выбор версии при установке Spark связан с версией hadoop. Нажмите, чтобы открыть ссылкуПосле ввода выберите подходящее изображение. При нормальных обстоятельствах можно использовать оба .

Заставьте FireFox fieldset имитировать IE в закругленных углах

Метка набора полей написана в Firefox, углы не закруглены, как в IE, что влияет на внешний вид. Мы можем установить стиль в fieldset: .

Установка MongoDB и базовый синтаксис

Метод вызова Notepad ++ и GVIM в Vivado

Метод вызова Notepad ++ и GVIM в Vivado Позвоните Notepad ++ Позвоните в метод GVIM, это не на этом, потому что в середине программных файлов есть пространство Правильный способ установки его на диск .

Вам также может понравиться

Mangacies-Chesboard танцы (мышление)

Не бойся! Не бойся! Не бойся! 90% мира очень просто. Этот вопрос на самом деле тщательно думает о том, чтобы принимать бумагу и покраску. Он чувствует себя больше в тестовом переводе. .

HDU4506 S Xiaoming Series Story-Brother Help

Ссылка на вопрос:HDU4506 S Xiaoming Series Story-Brother Help。 описание проблемы:Смотрите ссылки, описанные выше. Анализ проблем:(немного). Описание программы: Функция PowerMod () - функция быстрой мо.


Без названия

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


Как аудио конвертер перехватывает часть аудио

Когда я слышал несколько хороших песен, я всегда хотел взять музыкальные фрагменты и сделать из них рингтоны для мобильных телефонов. Хотя это и немного клише, но и человеческое. В эту эпоху безмолвия.

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