2016-06-12 196 views
1

我已經通過調用QUiLoader:使用自定義小部件加載.ui文件的要求?

QUiLoader().load(qfile_object, this); 

作品般的魅力創造了使用QT5,設計師,我在運行時加載UI但現在我已經提拔一些QLabel元素到窗口小部件類MyQLabel與從QLabel的。

現在當我嘗試加載我得到的UI控件促進每個警告:

"QFormBuilder was unable to create a custom widget of the class 'MyQLabel'; defaulting to base class 'QLabel'." 

類看起來是這樣的:

class MyQLabel : public QLabel { 
    Q_OBJECT 
    public: 
    MyQLabel(QWidget *parent = nullptr) : QLabel(parent) {} 
}; 

它已經自動moc「編輯和鏈接對我的可執行文件

我有,不知怎的,我嘗試使用它之前告訴QUiLoader我的類,但我不知道怎麼的感覺..

我必須爲此創建插件?有沒有辦法重現,QUiLoader做什麼來檢查它?

回答

1

您需要創建您自己的衍生版本QUiLoader,並提供可以創建您的小部件的工廠方法QUiLoader::createWidget的實現。

你可以把它分解成一個由QUiLoader加載的插件。它必須實現一個QDesignerCustomWidgetInterface實例。有關插件的完整示例,請參閱Custom Widget Plugin Example

// https://github.com/KubaO/stackoverflown/tree/master/questions/uiloader-custom-37775472 
#include <QtUiTools> 
#include <QtWidgets> 

const char uiData[] = 
    "<ui version=\"4.0\"><class>Widget</class><widget class=\"MyWidget\" name=\"Widget\">\n" 
     "<property name=\"windowTitle\" ><string>Widget</string></property>\n" 
     "</widget><pixmapfunction></pixmapfunction><resources/><connections/>\n" 
    "</ui>"; 

class MyWidget : public QLabel 
{ 
    Q_OBJECT 
    bool m_closed = false; 
public: 
    MyWidget(QWidget* parent = 0) : QLabel("This is MyWidget", parent) {} 
    bool isClosed() const { return m_closed; } 
    void closeEvent(QCloseEvent *) Q_DECL_OVERRIDE { m_closed = true; } 
}; 

class MyUiLoader : public QUiLoader { 
public: 
    MyUiLoader(QObject * parent = 0) : QUiLoader(parent) {} 
    QWidget * createWidget(const QString & className, QWidget * parent = 0, 
          const QString & name = QString()) { 
     if (className == "MyWidget") { 
      MyWidget * w = new MyWidget(parent); 
      w->setObjectName(name); 
      return w; 
     } 
     return QUiLoader::createWidget(className, parent, name); 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 
    QBuffer buf; 
    buf.setData(uiData, sizeof(uiData)); 
    MyUiLoader uiLoader; 
    auto uiMain = qobject_cast<MyWidget*>(uiLoader.load(&buf)); 
    uiMain->show(); 
    return app.exec(); 
} 

#include "main.moc"