Imported module but still need to use full name - python

I've been able to successfully import QtWidgets from PyQt5 and this works fine in code however if I don't use the full QtWidgets name in the call I get an error. Below works...
import sys
from PyQt5 import QtWidgets
app = QtWidgets.QApplication(sys.argv)
Yet if do...
import sys
from PyQt5 import QtWidgets
app = QApplication(sys.argv)
I get ...
NameError: name 'QApplication' is not defined

Your misunderstanding how Python import statements work. When importing a module in Python, only the module directly imported is include in the local symbol table.
Thus, if you have not directly imported a name, it cannot be used as a standalone identifier in the current namespace. If you want this behavior, directly import the QApplication name from the QtWidgets namespace:
from PyQt5.QtWidgets import QApplication

Import modules like this:
import sys
from PyQt5.QtWidgets import *
app = QApplication(sys.argv)

Related

How to determine what to import for, for example, the matchFlags used with QTreeWidget.findItems?

I am trying to use function QTreeWidget.findItems to find an exact match (the item is named "Things")
I saw an example using this ... Qt.MatchExactly ... as the 'match flag'.
even though i had imported Qt module from PyQt5, the MatchExactly was not found.
I got it to work by importing ANOTHER Qt module found in QtCore in PyQt5. but that was after many hours over several days of poking, guessing, and reading stackOverFlow posts.
My question is - how to know what module contains (and therefore must be imported) the stuff I need? how would I know that Qt.MatchExactly is in the PyQt5.QtCore.Qt module (and NOT in PyQt5.Qt module)?
This is my code: Note it reads in a QtDesigner .ui file, so its not gonna work for you. but having you run this code is not the point.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtWidgets import QMainWindow, QApplication, QTreeWidgetItem
from PyQt5 import uic, QtWidgets, Qt #<<flags are not here
from PyQt5 import QtCore
from PyQt5.QtCore import Qt #<<<this is where i found the match flag "MatchExactly"
qtCreatorFile = "Main2.ui" # Enter qt Designer file here.
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class MyApp(QMainWindow):
def __init__(self):
super(MyApp, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.InitModelContentTree()
def InitModelContentTree (self):
modelContentTree = self.ui.ModelContentTree
ThingsItemList = modelContentTree.findItems("Things", Qt.MatchExactly)
ThingsItem = ThingsItemList[0]
QTreeWidgetItem(ThingsItem, ["New Thing"])
print("pause")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
i'm hoping there is a decoder ring, some basic thing i'm missing. i'm proving to be a very bad, very inefficient guesser.
Actually Qt.MatchExactly is in Qt but you must import it in another way:
from PyQt5 import Qt
# ...
ThingsItemList = modelContentTree.findItems("Things", Qt.Qt.MatchExactly)
TL; DR
The Qt submodule is a fake module that allows access to any module such as an alias, for example it is similar to:
from PyQt5 import QtCore as Qt
from PyQt5 import QtGui as Qt
from PyQt5 import QtWidgets as Qt
# ...
# The same for all submodules
For example it can be checked for Qt.MatchExactly:
from PyQt5 import Qt, QtCore
assert(QtCore.Qt.MatchExactly == Qt.Qt.MatchExactly)
So in general the following import:
from PyQt5 import somemodule
somemodule.someclass
It is equivalent to:
from PyQt5 import Qt
Qt.someclass
How to know what submodule a class belongs to?: Well, if you have an IDE that can do a self-report like pycharm, the task is simple since the IDE itself does it. But if I do not have access to the IDE the other option is to use the docs of Qt, for example the docs of Qt::MatchExactly is in this link that in the first part is the following table:
And observe Qt += core so all the elements of that docs belong to the core sub-module of Qt that in PyQt/PySide corresponds to QtCore (in general if the docs of Qt indicate Qt += mymodule in PyQt/PySide in QtMyModule).Also the Qt::MatchExactly of C ++ corresponds to Qt.MatchExactly in python. So in conclusion you should use:
from PyQt5 import QtCore
QtCore.Qt.MatchExactly

Why python not show in path icon?

I wrote below code
import sys,time
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
app = QApplication(sys.argv)
sys.path.append(r"C:\Users\hpaalm\Desktop")
a=QPushButton()
a.setIcon(QIcon('1.png'))
a.show()
app.exec_()
when i run it in IDE, it show my icon, but when run it in CMD it not show icon. what is problem?
python C:\Users\hpaalm\Desktop\a.py
sys.path contains a list of paths where python imports the modules, this does not serve to import files, icons or similar resources. Instead it is best to create a function that binds the directory path with the filename and return the full path of the icon:
import os
import sys
from PyQt5 import QtGui, QtWidgets
ICON_DIR = r"C:\Users\hpaalm\Desktop"
def get_path_icon(filename):
return os.path.join(ICON_DIR, filename)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
a = QtWidgets.QPushButton()
a.setIcon(QtGui.QIcon(get_path_icon('1.png')))
a.show()
sys.exit(app.exec_())

youtube video embedding pyqt

How Can I embed youtube video using PyQt5? I tried doing the following,but it gave me an unresolved error:
DirectShowService:doRender unresolved error code
from PyQt5 import QtWidgets,QtCore,QtGui
import sys, time
from PyQt5.QtCore import Qt,QUrl
from PyQt5 import QtWebKit
from PyQt5 import QtWebKitWidgets
from PyQt5.QtWebKit import QWebSettings
#from PyQt5 import QtWebEngineWidgets #import QWebEngineView,QWebEngineSettings
class window(QtWidgets.QMainWindow):
def __init__(self):
QWebSettings.globalSettings().setAttribute(QWebSettings.PluginsEnabled,True)
super(window,self).__init__()
self.centralwid=QtWidgets.QWidget(self)
self.vlayout=QtWidgets.QVBoxLayout()
self.webview=QtWebKitWidgets.QWebView()
self.webview.setUrl(QUrl("https://www.youtube.com/watch?v=Mq4AbdNsFVw"))
self.vlayout.addWidget(self.webview)
self.centralwid.setLayout(self.vlayout)
self.setCentralWidget(self.centralwid)
self.show()
app=QtWidgets.QApplication([])
ex=window()
sys.exit(app.exec_())
You are importing some deprecated modules from PyQt5 (QtWebKit, and QtWebKitWidgets). It seems you have the right paths commented out at the bottom of your imports.
If you resolve these issues and use the proper modules (QtWebEngineCore, QtWebEngineWidgets) it works on my system.
from PyQt5 import QtWidgets,QtCore,QtGui
import sys, time
from PyQt5.QtCore import Qt,QUrl
from PyQt5 import QtWebEngineWidgets
from PyQt5 import QtWebEngineCore
from PyQt5.QtWebEngineWidgets import QWebEngineSettings
class window(QtWidgets.QMainWindow):
def __init__(self):
QWebEngineSettings.globalSettings().setAttribute(QWebEngineSettings.PluginsEnabled,True)
super(window,self).__init__()
self.centralwid=QtWidgets.QWidget(self)
self.vlayout=QtWidgets.QVBoxLayout()
self.webview=QtWebEngineWidgets.QWebEngineView()
self.webview.setUrl(QUrl("https://www.youtube.com/watch?v=Mq4AbdNsFVw"))
self.vlayout.addWidget(self.webview)
self.centralwid.setLayout(self.vlayout)
self.setCentralWidget(self.centralwid)
self.show()
app=QtWidgets.QApplication([])
ex=window()
sys.exit(app.exec_())
The output I get looks like the following (which seems correct):

How to import a module in Python which is already imported in another file? [duplicate]

This question already has an answer here:
python import multiple times [duplicate]
(1 answer)
Closed 5 years ago.
In my gui.py module I have:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
...
How do I correctly import everything from that module in my main.py without from gui import * Should I again use in my from PyQt5 import QtCore ... or from gui import QtCore ...?
In general, you shouldn't import stuff from a module which itself has only imported it:
# gui.py
from PyQt5 import QtCore, QtGui, QtWidgets
def some_function():
pass
you should then do:
# main.py
from PyQt5 import QtCore, QtGui, QtWidgets
from gui import some_function
The only exception are __init__.py files that aggregate modules from its submodules for convenience reasons:
# some_module/__init__.py
from .submodule import some_function
from .other_submodule import some_other_function
and then
# main.py
from .some_module import some_function, some_other_function
Since the're not modules that are provided by gui you should just import them directly from PyQt5.

How can you easily select between PyQt or PySide at runtime?

I would like to do something like this in one source file, QT.py:
import sys
import PyQt4
sys.modules["Qt"] = PyQt4
Then import this file in the other source files, and use it like this:
import QT
from Qt.QtCore import *
So I can change from PyQt4 to PySide in QT.py without touching all the source files (with a possibly ugly sed script)
These modules are mostly API compatibile and I would like to test them both. Is there an easy way to do this? (Because the ways I tried are not working)
Maybe the I need imp module, but it seems too low level.
Any ideas?
Use an import hook:
def set_qt_bindings(package):
if package not in ('PyQt4', 'PySide'):
raise ValueError('Unknown Qt Bindings: %s' % package)
import __builtin__
__import__ = __builtin__.__import__
def hook(name, globals=None, locals=None, fromlist=None, level=-1):
root, sep, other = name.partition('.')
if root == 'Qt':
name = package + sep + other
return __import__(name, globals, locals, fromlist, level)
__builtin__.__import__ = hook
if __name__ == '__main__':
import sys
if len(sys.argv) > 1:
set_qt_bindings(sys.argv[-1])
import Qt
print Qt
from Qt import QtCore
print QtCore
from Qt.QtGui import QWidget
print QWidget
Output:
$ python2 test.py PySide
<module 'PySide' from '/usr/lib/python2.7/site-packages/PySide/__init__.py'>
<module 'PySide.QtCore' from '/usr/lib/python2.7/site-packages/PySide/QtCore.so'>
<type 'PySide.QtGui.QWidget'>
$ python2 test.py PyQt4
<module 'PyQt4' from '/usr/lib/python2.7/site-packages/PyQt4/__init__.pyc'>
<module 'PyQt4.QtCore' from '/usr/lib/python2.7/site-packages/PyQt4/QtCore.so'>
<class 'PyQt4.QtGui.QWidget'>
update: Figured out method more in line with your requirements:
You can structure your pseudo-module as:
Qt/
Qt/__init__.py
Qt/QtCore/__init__.py
Qt/QtGui/__init__.py
Where Qt/__init__.py is:
import QtCore, QtGui
Qt/QtCore/__init__.py is:
from PyQt4.QtCore import *
Qt/QtGui/__init__.py is:
from PyQt4.QtGui import *
Then, in your code, you can reference it as follows:
import sys
from Qt import QtGui
app = QtGui.QApplication(sys.argv)
from Qt.QtGui import *
window = QWidget()
window.show()
app.exec_()
I highly recommend against using from Qt.QtGui import * in your code as importing everything is considered bad form in Python since you lose all namespaces in the process.
update:
I like Ryan's suggestion of conditional imports. I'd recommend combining that into the above code. For example:
Qt/QtGui/__init__.py:
import sys
if '--PyQt4' in sys.argv:
from PyQt4.QtGui import *
else:
from PySide.QtGui import *
You can conditionally import libraries. Here is a bit of a hacky example, where you check for a command-line argument of "PyQt4":
import sys
if sys.argv[-1] == 'PyQt4':
import PyQt4
sys.modules["Qt"] = PyQt4
else:
import Qt
from Qt.QtCore import *

Categories