Проблемы с Pynput и Pyinstaller в Ubuntu 20.04LTS GUI

#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