编程语言
首页 > 编程语言> > python-在QtWidgets.QApplication(sys.argv)之后无法导入PyQt模块

python-在QtWidgets.QApplication(sys.argv)之后无法导入PyQt模块

作者:互联网

总览

我在下线后导入模块时遇到麻烦
QtWidgets.QApplication(sys.argv),假设我得到了这个小片段main.py:

import sys
import importlib
from PyQt5 import QtWidgets

print('Sys Path:')
print('  %s\n' % '\n  '.join(sys.path))

if sys.argv[-1] == '1':
    print('Importing Before...\n')
    from PyQt5 import Qt
    app = QtWidgets.QApplication(sys.argv)

elif sys.argv[-1] == '2':
    print('Importing After...\n')
    app = QtWidgets.QApplication(sys.argv)
    from PyQt5 import Qt

print('Done')

>如果我运行python main.py 1,一切都会按预期进行.
>如果我运行python main.py 2,则进程挂起(可能处于无限循环中),而没有给出任何错误.

python main.py 2的输出:

(py352) D:\sources\personal\python\pyqt\mcve>python main.py 2           
Sys Path:                                                               
  D:\sources\personal\python\pyqt\mcve                                  
  D:\sources\personal\python                                            
  d:\virtual_envs\py352\Scripts\python35.zip                            
  d:\virtual_envs\py352\DLLs                                            
  d:\virtual_envs\py352\lib                                             
  d:\virtual_envs\py352\Scripts                                         
  c:\Python352\Lib                                                      
  c:\Python352\DLLs                                                     
  d:\virtual_envs\py352                                                 
  d:\virtual_envs\py352\lib\site-packages                               

Importing After...                                                      
(HANG)

尝试

在win7上对几个virtualenvs进行了测试:

> Win7上Win32上的Python 3.5.1(v3.5.1:37a07cee5969,2015年12月6日,01:54:25)[MSC v.1900 64位(AMD64)]
> Win32上的Python 3.5.2(v3.5.2:4def2a2901a5,2016年6月25日,22:01:18)[MSC v.1900 32位(Intel)]

Pyqt使用pip安装在virtualenvs上,版本如下:

>>> QtCore.QT_VERSION
329472
>>> QtCore.QT_VERSION_STR
'5.7.0'
>>> QtCore.PYQT_VERSION_STR
'5.7'

相关信息

#pyqt freenode频道的一些非常好的人帮助我测试了存储库,但是他们都无法重现该问题,他们使用的python版本和平台是:

> win10-3.5.2 | Anaconda 4.1.1(64位)
> win8-3.5.2(v3.5.2:4def2a2901a5,2016年6月25日,22:01:18)
> ubuntu 16.04-3.5.2(默认,2016年11月17日,17:05:23)

问题

>从PyQt5导入Qt(或其他pyqt模块)卡在我的盒子上,而其他人无法复制的原因是什么?
>如何解决此问题?这对我很重要,因为我要在pyqt应用程序启动后动态加载插件

解决方法:

这还不是一个真正的答案,但是它可能提供了找到答案的第一步.

以下是我在对该问题的第一条评论中建议的最小测试用例.它仅测试一件事:创建QApplication之后调用importlib.import_module是否会使解释器挂在您的系统上?请注意,目前,它仅尝试从python标准库中导入模块.一次执行一个步骤非常重要,并要小心避免引入任何可能引起混淆的变量.

请完全按照以下说明运行此脚本,然后将输出添加到您的问题中. (即使选项2没有挂起,sys.path详细信息也可能是相关的).

import sys, importlib
from PyQt5 import QtWidgets

print('Sys Path:')
print('  %s\n' % '\n  '.join(sys.path))

mod = None
modname = 'collections.abc'
# modname = 'PyQt5.Qt'

if sys.argv[-1] == '1':
    print('Importing Before...\n')
    mod = importlib.import_module(modname)
    app = QtWidgets.QApplication(sys.argv)

elif sys.argv[-1] == '2':
    print('Importing After...\n')
    app = QtWidgets.QApplication(sys.argv)
    mod = importlib.import_module(modname)
    # from PyQt5 import Qt

print('Result: %r' % mod)

像这样运行脚本:

$python /tmp/test.py 1

然后像这样:

$python /tmp/test.py 2

在我的系统(ArchLinux,Python-3.5.2,Qt-5.7.1,PyQt-5.7)上,第二个产生以下输出:

Sys Path:
  /tmp
  /usr/lib/python35.zip
  /usr/lib/python3.5
  /usr/lib/python3.5/plat-linux
  /usr/lib/python3.5/lib-dynload
  /usr/lib/python3.5/site-packages

Importing After...

Result: <module 'collections.abc' from '/usr/lib/python3.5/collections/abc.py'>

更新:

第一步是确定importlib本身不是问题的原因.第二步是确定哪个特定的导入模块是问题的根源.

我在测试脚本中添加了两行(注释),可以完成此操作.第一个检查导入PyQt5.Qt是否触发挂起.如果是这样,则第二个命令检查正常的import语句是否也会触发挂起.

请注意,从PyQt5导入,Qt有效地导入了所有内容,包括一些重量级和可能麻烦的模块,例如QtWebEngineWidgets.因此,有必要进一步完善进口以正确确定问题的确切根源.

更新2:

QtWebEngineWidgets是一个众所周知的问题源,通常需要仔细处理.以下解释器会话输出似乎与您当前的问题有关:

>>> from PyQt5 import QtWidgets, QtCore
>>> app = QtWidgets.QApplication([''])
>>> from PyQt5 import QtWebEngineWidgets
Qt WebEngine seems to be initialized from a plugin. Please set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute before constructing QGuiApplication.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: QtWebEngineWidgets must be imported before a QCoreApplication instance is created
>>>
>>> QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts)
>>> from PyQt5 import QtWebEngineWidgets
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: QtWebEngineWidgets must be imported before a QCoreApplication instance is created

这是所有正常行为(尽管目前我找不到任何官方文档).但是,让我们使用Qt模块尝试同样的事情:

>>> from PyQt5 import QtWidgets, QtCore
>>> QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts)
>>> app = QtWidgets.QApplication([''])
>>> from PyQt5 import Qt
>>> Qt.QWeb
Qt.QWebChannel(                      Qt.QWebEngineUrlRequestInterceptor(  Qt.QWebHitTestResult(                Qt.QWebSocketCorsAuthenticator(
Qt.QWebChannelAbstractTransport(     Qt.QWebEngineUrlRequestJob(          Qt.QWebInspector(                    Qt.QWebSocketProtocol(
Qt.QWebDatabase(                     Qt.QWebEngineUrlSchemeHandler(       Qt.QWebPage(                         Qt.QWebSocketServer(
Qt.QWebElement(                      Qt.QWebFrame(                        Qt.QWebPluginFactory(                Qt.QWebView(
Qt.QWebElementCollection(            Qt.QWebHistory(                      Qt.QWebSecurityOrigin(
Qt.QWebEngineCookieStore(            Qt.QWebHistoryInterface(             Qt.QWebSettings(
Qt.QWebEngineUrlRequestInfo(         Qt.QWebHistoryItem(                  Qt.QWebSocket(
>

因此,在创建QApplication之后导入Qt模块时,似乎对Qt模块进行了特殊处理-尽管可以使用某些QWebEngine类,但大多数类已被省略(例如QWebEngineView,QWebEnginePage等).但是似乎在您的特定设置中,这可能无法正常工作.如果是这样,您可能需要与PyQt的作者联系,因为它可能需要了解Qt模块的内部工作原理.

标签:pyqt5,python-3-5,python-import,python,windows-7
来源: https://codeday.me/bug/20191111/2023469.html