I am a newbie and am just starting to learn Python programming:
import sys
from PyQt5 import QtWidgets
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWindow = QtWidgets.QMainWindow()
mainWindow.show()
sys.exit(app.exec_())
When I run the above code, every is OK. But when I run the code below, it fails with the following error message: app = PyQt5.QtWidgets.QApplication(sys.argv) AttributeError: 'module' object has no attribute 'QtWidgets'
import sys
import PyQt5
if __name__ == "__main__":
app = PyQt5.QtWidgets.QApplication(sys.argv)
mainWindow = PyQt5.Qtwidgets.QmainWindow()
mainWindow.show()
sys.exit(app.exec_())
By the way, my Python version is 2.7, I'm using Qt5 library and my operating system is OpenSUSE 13.2, of course, a distribution of Linux.
The PyQt5
part just provides a namespace for a group of modules. It doesn't contain anything itself, and so you cannot import anything directly from it.
This is a deliberate design decision, and is done for a good reason. There could be a total of thirty or more modules in the package, so it would be a heavy up-front cost to load them all every time PyQt5
itself was imported. So instead, the intention is to only pay the cost of loading the modules you actually need.
However, there may be times when you do want to load all the modules at once. For instance, it would be very convenient to be able to do this when experimenting in a python interactive session. And in fact, PyQt provides a special module that does exactly that:
>>> from PyQt5 import Qt
>>> Qt.QWidget
<class 'PyQt5.QtWidgets.QWidget'>
>>> Qt.QObject
<class 'PyQt5.QtCore.QObject'>
>>> Qt.QNetworkCookie
<class 'PyQt5.QtNetwork.QNetworkCookie'>
The Qtwidgets
file is a compiled .so
file in the PyQt5
directory, as are all the modules, there are no imports in the __init__.py
file so you need to use from ...
An example using a cython compiled file test1.cpython-34m.so
in a directory py3
with an empty __init.__py
exhibits the same behaviour:
In [1]: import py3
In [2]: py3.test1
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-2-9aa45b2a49b6> in <module>()
----> 1 py3.test1
AttributeError: 'module' object has no attribute 'test1'
In [3]: from py3 import test1
In [4]: test1.foo()
Out[4]: 100
The files in PyQt5 are as below:
/usr/lib/python3/dist-packages/PyQt5$ ls
__init__.py
__pycache__
_QOpenGLFunctions_2_0.cpython-34m-x86_64-linux-gnu.so
QtCore.cpython-34m-x86_64-linux-gnu.so
Qt.cpython-34m-x86_64-linux-gnu.so
QtDBus.cpython-34m-x86_64-linux-gnu.so
QtDesigner.cpython-34m-x86_64-linux-gnu.so
QtGui.cpython-34m-x86_64-linux-gnu.so
QtHelp.cpython-34m-x86_64-linux-gnu.so
QtNetwork.cpython-34m-x86_64-linux-gnu.so
QtOpenGL.cpython-34m-x86_64-linux-gnu.so
QtPrintSupport.cpython-34m-x86_64-linux-gnu.so
QtTest.cpython-34m-x86_64-linux-gnu.so
QtWidgets.cpython-34m-x86_64-linux-gnu.so
uic
Using cat
you can see that there are no imports in __init__.py
:
$:/usr/lib/python3/dist-packages/PyQt5$ cat __init__.py
# Copyright (c) 2014 Riverbank Computing Limited <[email protected]>
#
# This file is part of PyQt5.
#
# This file may be used under the terms of the GNU General Public License
# version 3.0 as published by the Free Software Foundation and appearing in
# the file LICENSE included in the packaging of this file. Please review the
# following information to ensure the GNU General Public License version 3.0
# requirements will be met: http://www.gnu.org/copyleft/gpl.html.
#
# If you do not wish to use this file under the terms of the GPL version 3.0
# then you may purchase a commercial license. For more information contact
# [email protected].
#
# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
# WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
So because there are no imports in the __init__.py
when you try to use PyQt5.Qtwidgets
you get the error you see as the module obviously has no attributes.
If you added something like from . import QtWidgets
to the __init__.py
you could then use import PyQt5 PyQt5.Qtwidgets
or PyQt5.Qtwidgets
would also work with a blank init as you are importing the module Qtwidgets
from the package PyQt5
.
You can see when you import PyQt5
you then you actually have a module:
In [6]: import PyQt5
In [7]: type(PyQt5)
Out[7]: module
So the real difference and why you see the output you do is you are trying to import from a module in the second example and a package in the first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With