在 .ui 文件中调用自定义类失败 [英] Calling custom class in .ui file fails

查看:43
本文介绍了在 .ui 文件中调用自定义类失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试从 .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 文件中调用自定义类失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆