问题描述
当我尝试从 .ui
文件引用我的自定义类时出现此错误.我的做法有什么问题?
I get this error when I try to refer to my custom class from .ui
file. What's wrong with what I do?
"QFormBuilder was unable to create a custom widget of the class 'TimelinePane'; defaulting to base class 'QWidget'."
QWidget
弹出我在 .ui
文件中指定的布局.问题只是自定义类.
QWidget
pops up with the layout I'm specifying in .ui
file. Problem is just the custom class.
为了添加自定义类的描述,我手动修改了 .ui
文件(添加了整个 部分),这就是为什么我必须打开一个新问题,因为我还没有找到相同的 Q.我怀疑
.ui
文件中类的路径,但我尝试过的选项(请参阅我注释掉的部分)都不起作用.我也猜想使用 python
不应该是这里的问题,但我不完全确定.还没试过C++
.
To add the custom class' description, I modified .ui
file manually (added the entire <customwidgets>
section), which is why I have to open a new question since I haven't found the same Q yet. I suspect the path of the class in .ui
file but none of the options I tried (see the part I commented out) worked. I also guess that using python
should not be the matter here but am not entirely sure. Haven't tried C++
yet.
from PySide import QtGui
from PySide import QtCore
from PySide import QtUiTools
class MyWidget(QtGui.QMainWindow):
def __init__(self, *args):
apply(QtGui.QMainWindow.__init__, (self,) + args)
loader = QtUiTools.QUiLoader()
file = QtCore.QFile('./src/prove_qt_ui_file/prove_main_widget.ui')
file.open(QtCore.QFile.ReadOnly)
self.myWidget = loader.load(file, self)
file.close()
self.setCentralWidget(self.myWidget)
if __name__ == '__main__':
import sys
import os
print("Running in " + os.getcwd() + " .\n")
app = QtGui.QApplication(sys.argv)
win = MyWidget()
win.show()
app.exec_()
prove_main_widget.ui
prove_main_widget.ui
<?xml version="1.0" encoding="UTF-8" ?>
<ui version="4.0">
<class>MyWidget</class>
<widget class="QWidget" name="MyWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>687</width>
<height>698</height>
</rect>
</property>
<property name="windowTitle">
<string>Runtime Monitor</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="handleWidth">
<number>9</number>
</property>
<widget class="QTreeWidget" name="warn_tree">
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
<widget class="QTreeWidget" name="tree_all_devices">
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
<widget class="TimelinePane" name="timeline_pane" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>80</height>
</size>
</property>
<property name="whatsThis">
<string extracomment="Timeline"/>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>TimelinePane</class>
<extends>QWidget</extends>
<!-- <header>timeline_pane</header> --> <!-- NG -->
<!-- <header>prove_qt_ui_file.timeline_pane</header> --> <!-- NG -->
<header>src.prove_qt_ui_file.timeline_pane</header> <!-- NG -->
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
timeline_pane.py
timeline_pane.py
from PySide.QtGui import QWidget, QGraphicsScene, QGraphicsView, QColor, QHBoxLayout, QPushButton
class TimelinePane(QWidget):
def __init__(self, parent):
super(TimelinePane, self).__init__()
print '\tTimelinePane init 1' # This doesn't print.
(环境)Ubuntu 12.04,python 2.7.3
(Environment) Ubuntu 12.04, python 2.7.3
推荐答案
理论上,要让自定义小部件工作,您只需调用:
In theory, to have your custom widget work you should only have to call:
loader.registerCustomWidget(TimelinePane)
在调用 loader.load() 之前.您需要在您的情况下添加相关的导入语句:
before calling loader.load(). You need to add the relevant import statements, in your case:
from timeline_pane import TimelinePane
然而,我刚刚在 Ubuntu 12.04 x86_64 上用 PySide 1.1.2 测试了这个,它导致了段错误.YMMV,所以请测试.
However, I just tested this with PySide 1.1.2 on Ubuntu 12.04 x86_64, and it caused a segfault. YMMV, so please test.
我最终实施了这个解决方法:http://www.mail-archive.com/pyside@qt-project.org/msg00306.html
I ended up implementing this workaround: http://www.mail-archive.com/pyside@qt-project.org/msg00306.html
简而言之,覆盖QUiLoader的creteWidget()方法,如果widget的class_name不在self.availableWidgets()中,根据自己添加的customWidgets实例变量自行实例化.
In short, override the QUiLoader's creteWidget() method, and if the class_name of the widget is not in self.availableWidgets(), instantiate it yourself according to the customWidgets instance variable that you've added.
顺便说一句,您也可以使用 Qt Designer 中的右键单击Promote To"功能,而不是直接编辑 ui 文件.
BTW, you can also make use of the right-click "Promote To" functionality in the Qt Designer instead of editing the ui file directly.
这篇关于在 .ui 文件中调用自定义类失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!