Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PyQt中的QUiLoader.createWidget等效项_Python_Pyqt_Pyside - Fatal编程技术网

Python PyQt中的QUiLoader.createWidget等效项

Python PyQt中的QUiLoader.createWidget等效项,python,pyqt,pyside,Python,Pyqt,Pyside,我有一个PySide应用程序,我正在研究使其与PyQt4兼容。显然,这应该不会太难,但我希望尽量减少必要的代码更改。我遇到的最大区别(影响我的程序)是PyQt没有包装QUiLoader类 现在我意识到我仍然可以用PyQt中的uic模块加载ui文件,但是我目前在PySide中使用了QUiLoader的子类,该子类实现了一些自定义功能,如果可能的话,我希望保留这些功能 功能如下所示。我对QUiLoader进行了子类化,并重写了createWidget()方法。我的新实现允许您在应用程序运行时动态注册

我有一个PySide应用程序,我正在研究使其与PyQt4兼容。显然,这应该不会太难,但我希望尽量减少必要的代码更改。我遇到的最大区别(影响我的程序)是PyQt没有包装
QUiLoader

现在我意识到我仍然可以用PyQt中的uic模块加载ui文件,但是我目前在PySide中使用了
QUiLoader
的子类,该子类实现了一些自定义功能,如果可能的话,我希望保留这些功能

功能如下所示。我对
QUiLoader
进行了子类化,并重写了
createWidget()
方法。我的新实现允许您在应用程序运行时动态注册小部件升级。我之所以能够这样做,是因为
createWidget()
方法负责从ui文件实例化小部件,然后(我相信)标准QUiLoader实现应用ui文件中指定的属性

我的问题是,我是否可以在PyQt中重写类似的方法,以便在运行时动态设置小部件升级,而不必通过Qt设计器和ui文件静态设置它

另外,我正在寻找一种对现有代码进行最小更改的解决方案。例如,如果我可以用一个在PyQt下提供等效行为的类替换PySide
QUiLoader
子类,那将是理想的

编辑: 该实现的使用方式如下:

loader = UiLoader()
loader.registerCustomPromotion("myWidgetNameInQtDesigner",ClassToPromoteTo)
ui = loader.load('myUiFile.ui')

这就是我在PySide中使用
QUiLoader
子类所做的。.ui文件中名为“
”myWidgetNameInQtDesigner“
的任何小部件都将被实例化为
ClassToPromoteTo

的实例,只要您愿意在Qt Designer中推广相关小部件,这将非常容易

其思想是向sys.modules添加一个虚拟模块,然后动态修改它包含的自定义小部件类

因此,如果在Qt Designer中升级小部件时将“头文件”设置为“mylib.dummy”,则在使用PyQt加载ui文件时,您将执行以下操作:

from types import ModuleType

# dummy module
module = sys.modules['mylib.dummy'] = ModuleType('dummy')

if mode == 'FOO':
    module.TextEdit = FooTextEdit
    module.LineEdit = FooLineEdit
    module.PushButton = FooPushButton
elif mode == 'BAR':
    module.TextEdit = BarTextEdit
    module.LineEdit = BarLineEdit
    module.PushButton = BarPushButton
else:
    module.TextEdit = QTextEdit
    module.LineEdit = QLineEdit
    module.PushButton = QPushButton

# loadUi/loadUiType will add the following import line:
# from mylib.dummy import TextEdit, LineEdit, PushButton
WidgetUI = uic.loadUiType('mywidget.ui'))[0]
ui = WidgetUI()

看看这个,有一个代码可以用另一种方式来实现,例如PyQT->PySide。也许你会发现它很有用。@Fenikso类似的PySide代码启发我在PySide中编写自己的
QUiLoader
子类,它允许动态升级。我可能应该澄清一下,它允许将ui文件中的任何小部件动态升级到您自己的小部件子类。你链接到我的PyQt代码只允许在没有父级的顶级小部件上使用它(据我所见)。@three_Pinepples。你真的需要动态升级任何小部件吗?这个用例是什么?更一般地说,运行时动态升级的用例是什么?如果您能给出一个基本的、有效的示例,说明您实际需要的最低功能,这将非常有用。@ekhumoro我正在代码中动态升级小部件。我可以重写我的代码,这样我就不需要了吗?也许吧,但这将是一个公平的工作,我想避免位。就我所见,我必须在Python代码中实例化自定义小部件,应用我在Qt Designer中为基本小部件设置的任何属性,从ui文件中删除基本实例,然后将自定义小部件实例添加到Qt Designer中曾经分配给它的任何布局/小部件。同样,显然是可能的,但如果可以的话,我宁愿尝试保持我当前的架构。谢谢,我想这样就可以了。我的PySide实现没有在Qt Designer中进行任何升级(这对于像
QMainWindow
这样的小部件很有用,它不能在Qt Designer中升级),但我认为在PyQt中实现这一点的唯一方法是分叉PyQt4.uic模块并修改它的行为(我并不特别想这么做!)。不幸的是,当模块名为mylib.dummy时,我无法使它工作,但当它名为mylib时,它工作(
uic
引发导入错误)。有什么想法吗(并不是说它非常重要)?@三个菠萝。我确实用与上面相同的包结构测试了我的解决方案,导入对我来说很好。结构很简单:
main.py
lib/\uuuu init\uuuuu.py
lib/app.py
lib/classes.py
。至于分叉uic:我完全理解您为什么要避免这种情况——如果曾经有过维护噩梦的话,那就是维护噩梦!啊,我明白了。如果您使用
mylib.dummy
,您实际上必须拥有
mylib
模块的文件/文件夹结构。如果您只有“mylib”,则无需创建任何文件即可离开。干杯