Ubuntu 20.04LTS GUI 上的 Pynput 和 Pyinstaller 问题
Problems with Pynput and Pyinstaller on Ubuntu 20.04LTS GUI
我有一个使用 Pynput 模块的 python 脚本。当我 运行 来自 Ubuntu [20.04LTS GUI] 终端的 python 脚本时,它 运行 非常完美。
$ pyinstaller --onefile vTwo.py
cd ./dist
./vTwo
运行ning ./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 服务器在后台 运行ning,这应该不是问题,因为我安装了 GUI。
还有没有 gui 的系统可以使用 Pynput 吗?
解决方案
解决方法很简单。只需将此模块作为隐藏导入包含在 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'],
为什么会出错
当您在 PyInstaller 打包的 Python 程序中看到 ImportError
时,问题很可能是 PyInstaller 无法检测到该特定导入并且没有包含它在二进制文件中,因此出现导入错误。
在错误消息中,它告诉您找不到哪个模块:
ImportError: this platform is not supported: No module named 'pynput.keyboard._xorg'
这是 pynput.keyboard._xorg
,因为你在 Linux。
找不到模块,因为它是以“非传统”方式导入的。看backend
函数中pynput/_util/__init__.py
的源码:
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)) + ('\n\n'
'Try one of the following resolutions:\n\n'
+ '\n\n'.join(
' * {}'.format(s)
for s in resolutions))
if resolutions else '')
您可以看到它使用 importlib
模块中的 import_module
函数为平台导入正确的模块。这就是为什么它找不到
pynput.keyboard._xorg
模块。
你的第二个问题
还有在没有图形用户界面的系统上使用 Pynput 吗?
我不知道。
我有一个使用 Pynput 模块的 python 脚本。当我 运行 来自 Ubuntu [20.04LTS GUI] 终端的 python 脚本时,它 运行 非常完美。
$ pyinstaller --onefile vTwo.py
cd ./dist
./vTwo
运行ning ./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 服务器在后台 运行ning,这应该不是问题,因为我安装了 GUI。
还有没有 gui 的系统可以使用 Pynput 吗?
解决方案
解决方法很简单。只需将此模块作为隐藏导入包含在 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'],
为什么会出错
当您在 PyInstaller 打包的 Python 程序中看到 ImportError
时,问题很可能是 PyInstaller 无法检测到该特定导入并且没有包含它在二进制文件中,因此出现导入错误。
在错误消息中,它告诉您找不到哪个模块:
ImportError: this platform is not supported: No module named 'pynput.keyboard._xorg'
这是 pynput.keyboard._xorg
,因为你在 Linux。
找不到模块,因为它是以“非传统”方式导入的。看backend
函数中pynput/_util/__init__.py
的源码:
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)) + ('\n\n'
'Try one of the following resolutions:\n\n'
+ '\n\n'.join(
' * {}'.format(s)
for s in resolutions))
if resolutions else '')
您可以看到它使用 importlib
模块中的 import_module
函数为平台导入正确的模块。这就是为什么它找不到
pynput.keyboard._xorg
模块。
你的第二个问题
还有在没有图形用户界面的系统上使用 Pynput 吗?
我不知道。