#python #python-3.x #pynput
#python #python-3.x #pynput
Вопрос:
У меня есть скрипт на python, который использует модуль Pynput. Когда я запускаю скрипт python из терминала в Ubuntu [20.04LTS GUI], он работает отлично.
$ pyinstaller --onefile vTwo.py
cd ./dist
./vTwo
При запуске возникает ошибка ./script:
ImportError: this platform is not supported: No module named 'pynput.keyboard._xorg'
Try one of the following resolutions:
* Please make sure that you have an X server running, and that the DISPLAY environment variable is set correctly
[5628] Failed to execute script vTwo
Если бы кто-нибудь мог посоветовать мне, что может пойти не так. Я просмотрел страницу требований к Pynput, где упоминается, что для этого требуется, чтобы X server работал в фоновом режиме, что не должно быть проблемой, поскольку у меня установлен графический интерфейс.
Также есть ли возможность использовать Pynput в системе без графического интерфейса?
Ответ №1:
Решение
Решение простое. Просто включите этот модуль в качестве скрытого импорта в программу PyInstaller:
python -m PyInstaller your_program.py --onefile --hidden-import=pynput.keyboard._xorg
Если вы также используете мышь с pynput, то вы получите ту же ошибку с модулем pynput.mouse._xorg
. Итак, сделайте это:
python -m PyInstaller your_program.py --onefile --hidden-import=pynput.keyboard._xorg --hidden-import=pynput.mouse._xorg
Внимание! Скорее всего, вы получите другой модуль, который он не находит, если вы упаковываете для Windows или Mac. Это то, что вы получаете для Linux. Если вы хотите, чтобы ваша программа была кроссплатформенной, вам придется упаковать программу, например, для Windows, и протестировать ее, чтобы увидеть, какой модуль она не находит, и включить его в качестве скрытого импорта.
Например, если вы хотите, чтобы ваша программа работала в Linux и Windows, используйте эту команду:
python -m PyInstaller your_program.py --onefile --hidden-import=pynput.keyboard._xorg --hidden-import=pynput.mouse._xorg --hidden-import=pynput.keyboard._win32 --hidden-import=pynput.mouse._win32
Если у вас много скрытых модулей, вы можете отредактировать файл .spec и добавить модули в hiddenimports
список следующим образом (на PyInstaller 4.1):
hiddenimports=['pynput.keyboard._xorg', 'pynput.mouse._xorg'],
Почему ошибка
Когда вы видите ImportError
в программе Python, упакованной PyInstaller, существует высокая вероятность того, что проблема в том, что PyInstaller не смог обнаружить этот конкретный импорт и не включил его в двоичный файл, отсюда и ошибка импорта.
В сообщении об ошибке указывается, какой модуль он не нашел:
ImportError: this platform is not supported: No module named 'pynput.keyboard._xorg'
это pynput.keyboard._xorg
потому, что вы используете Linux.
Не удалось найти модуль, потому что он был импортирован «нетрадиционным» способом. Посмотрите на исходный код для pynput/_util/__init__.py
backend
функции in:
def backend(package):
backend_name = os.environ.get(
'PYNPUT_BACKEND_{}'.format(package.rsplit('.')[-1].upper()),
os.environ.get('PYNPUT_BACKEND', None))
if backend_name:
modules = [backend_name]
elif sys.platform == 'darwin':
modules = ['darwin']
elif sys.platform == 'win32':
modules = ['win32']
else:
modules = ['xorg']
errors = []
resolutions = []
for module in modules:
try:
return importlib.import_module('._' module, package)
except ImportError as e:
errors.append(e)
if module in RESOLUTIONS:
resolutions.append(RESOLUTIONS[module])
raise ImportError('this platform is not supported: {}'.format(
'; '.join(str(e) for e in errors)) ('nn'
'Try one of the following resolutions:nn'
'nn'.join(
' * {}'.format(s)
for s in resolutions))
if resolutions else '')
Вы можете видеть, что он использует import_module
функцию из importlib
модуля для импорта правильного модуля для платформы. Вот почему он не смог найти
pynput.keyboard._xorg
модуль.
Ваш второй вопрос
Также есть ли возможность использовать Pynput в системе без графического интерфейса?
Я не знаю.
Комментарии:
1. Чтобы решить ту же проблему в py2app , просто добавьте
OPTIONS = {'includes': ['pynput.keyboard._darwin', 'pynput.mouse._darwin']}
setup.py