QUiLoader:使用自定义小部件加载 .ui 文件的要求

QUiLoader: requirements for loading .ui file with custom widgets?

本文关键字:文件 ui 加载 自定义 小部 QUiLoader      更新时间:2023-10-16

我使用 Qt5-Designer 创建了一个 UI,我在运行时通过调用加载它

QUiLoader().load(qfile_object, this);

像魅力一样工作,但现在我已经将一些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怎么检查?

您需要

创建自己的派生版本的QUiLoader,并提供可以创建小部件的工厂方法QUiLoader::createWidget的实现。

您可以将此因素分解到由QUiLoader加载的插件中。它必须实现一个QDesignerCustomWidgetInterface实例。有关插件的完整示例,请参阅自定义控件插件示例。

// 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"