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

◇◆丶佛笑我妖孽 提交于 2019-12-30 09:43:31

问题


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?


回答1:


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 *



回答2:


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'>



回答3:


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 *


来源:https://stackoverflow.com/questions/8052386/how-can-you-easily-select-between-pyqt-or-pyside-at-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!