9

For my application, I need to set some widget parameters like alignment (Qt::AlignBottom) and others. But I can't import them (other PyQt5 stuff imports without any issues).

Using this code

from PyQt5 import Qt

progressBar = QProgressBar(splash)
progressBar.setAlignment(Qt.AlignBottom)

I got the following error:

Traceback (most recent call last):
  File "run_app.py", line 50, in <module>
    runSemApp(sys.argv)
  File "run_app.py", line 32, in runSemApp
    progressBar.setAlignment(Qt.AlignBottom)
AttributeError: 'module' object has no attribute 'AlignBottom'

And using this one works:

from PyQt5.Qt import *

progressBar = QProgressBar(splash)
progressBar.setAlignment(Qt.AlignBottom)

Though I have a working solution, I would like to import only Qt.AlignBottom and not *. Also, why doesn't Qt.AlignBottom work with from PyQt5 import Qt?

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
SS_Rebelious
  • 1,274
  • 2
  • 19
  • 35

3 Answers3

14

I think the confusion here is that PyQt has a special virtual module called Qt, which imports everything into a single namespace. This is a quite useful feature, but it's a real shame that the name clash with QtCore.Qt wasn't avoided.

In the first example, the error can be "fixed" by using the somewhat weird-looking Qt.Qt.AlignBottom. But obviously, explicitly importing from QtCore is a much better solution. It's also worth noting that the PyQt5 package is a lazy loader, so import PyQt5 will just import an empty namespace with no access to the other modules.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
7

You can do this

>>> from PyQt5.QtCore import Qt
>>> Qt.AlignBottom
64
>>>

You can't import AlignBottom only because QtCore is not a package itself, it's just a module on it's own (a single file). it's important to know that all packages are modules, but not all modules are packages

so this won't work

import PyQt5.QtCore.Qt

ImportError: No module named 'PyQt5.QtCore.Qt'; 'PyQt5.QtCore' is not a package
>>> import PyQt5.QtCore
>>> QtCore
<module 'PyQt5.QtCore' from '/usr/lib/python3.5/site-packages/PyQt5/QtCore.so'>
>>> import PyQt5
>>> PyQt5
<module 'PyQt5' from '/usr/lib/python3.5/site-packages/PyQt5/__init__.py'>
>>>

Looking at the output you can see that QtCore is a single file which contains a class Qt that contains other classes and methods on which AlignBottom is part of, you can see that with.

>>> from PyQt5.QtCore import Qt
>>> help(Qt)

On the otherhand PyQt5 is a package (folder containing other modules) points to it's __init__.py

i'll suggest you read the docs on Modules and this SO question

Community
  • 1
  • 1
danidee
  • 9,298
  • 2
  • 35
  • 55
  • 4
    I think the confusion here is that PyQt has a special virtual module called `Qt`, which imports *everything* into a single namespace. This is a quite useful feature, but it's a real shame that the name clash with `QtCore.Qt` wasn't avoided. In the OPs first example, the error can be "fixed" by using the somewhat weird-looking `Qt.Qt.AlignBottom`. But obviously, explicitly importing from `QtCore` is a much better solution. It's also worth noting that the PyQt5 package is a *lazy loader*, so `import PyQt5` will just import an empty namespace with no access to the other modules. – ekhumoro Sep 04 '16 at 15:42
  • @ekhumoro, if you post your comment as the answer I will accept it. – SS_Rebelious Sep 06 '16 at 05:33
0

If you''re using PySide - as of Pyside6, the QtCore has been refactored. The alignment flags are in the AlignmentFlag module. The following works for me (Python 3.10, Pyside 6, Ubuntu 22.04).

import Pyside6.QtCore as qtc
            
my_align = qtc.Qt.AlignmentFlag.AlignCenter | qtc.Qt.AlignmentFlag.AlignVCenter

title_label.setAlignment(my_align)
Matt
  • 500
  • 1
  • 12
  • 21