QtCreator 自定义模块问题

QtCreator Custom Module Issue

用可行的例子编辑

在 Windows7 64 位

上使用 Qt 5.10.0、QtCreator 4.5.0、Qt5.10.0 MSVC2015 32 位编译器

问题

创建自定义模块(所有文件从文件->新文件或项目...->Qt->QtQuick UI 文件自动生成)并尝试从外部拖放关联的 qml 文件后库(进入另一个目录中的某些 MainForm.ui.qml) 放置在 MainForm 中的对象的名称不正确,并且无法在 MainForm 中实例化所述对象。当没有模块并且所有主文件和对象 qml/ui.qml 文件都并置时,这一切都很好。

重现问题

制作项目 - 至于整个项目的结构,这将需要一些时间,但所有 qml 文件或多或少可以是自动生成的任何文件,问题仍然存在。

在QtCreator中点击File->New File or Project...->Application->Qt Quick Application。我把它命名为MyApp,用qmake制作,最低版本Qt 5.9,编译器Qt5.10.0 MSCV2015 32bit

从现在开始,当我说添加一个新的 QtQuickUI 文件时,我的意思是文件->新建文件或项目...->Qt->QtQuick UI 文件

复制main.qml的内容。使用 QtCreator Projects 窗格将新的 QtQuickUI 文件添加到 main.qml 所在的文件夹(在项目的资源文件夹下),名为 Main。它会告诉你 main.qml 已经存在,只需覆盖它。这将生成供设计人员使用的 Main.qml 和 Main.ui.qml。您很可能还必须从 qml.qrc 文件中删除旧的 main.qml。将之前 main.qml 的内容粘贴到 Main.qml.

现在在同一目录中以同样的方式创建一个名为 MyObject 的新 QtQuickUI 文件。如果您随后在设计器选项卡中打开 MainForm.ui.qml,并转到表单编辑器,您可以将 MyObject 从设计器库拖放到 MainForm 上。然后切换到文本编辑器你可以看到 MainForm.ui.qml 包含一个具有各种属性的 MyObject {}。请注意,目前 MyObject.qml 中包含的实际上是 "MyObjectForm{}"。这是转换为模块时会出现问题的地方。

在 MyObjectForm.ui.qml 文件中,我还放下了一个文本框,仅用于测试目的。

在 main.cpp 中,将引擎查找的 main.qml 路径更改为 "qrc:/Main.qml" 而不是使用小写的 main。然后在 Main.qml 中将 MainForm{} 添加到 Window{} 中,Window{andEverythingInIt} 是从旧的 main.qml 复制的内容以及它所需的导入。如果您 运行 qmake、构建并点击播放,您应该会在某个位置看到带有 "Text" 的空白 window。

制作模块
现在,在创建者之外,在 MyApp 目录中添加一个名为 Modules 的文件夹,并在其中添加一个名为 Objects 的文件夹。然后在Creator中,右击qml.qrc文件,添加现有目录,添加Modules文件夹。然后,在 creator 之外,将 MyObject.qml 和 MyObjectForm.ui.qml 移动到 Objects 文件夹。在创建器中右击qml.qrc,在编辑器中打开,将刚刚移动的两个文件重命名,在最前面追加Modules/Objects/。然后在 MyApp.pro 文件中将带引号的 "Modules" 添加到 QML_IMPORT_PATH 变量。同样在 main.cpp 中,在加载 Main.qml 文件之前添加 engine.addImportPath("../MyApp/Modules");。我不得不对路径进行硬编码,因为我还没有得到任何其他工作。我希望 "qrc:/Modules" 会起作用,但它没有。如果您使用设计器自动生成项目,默认情况下构建 folder/working 目录将与 MyApp 位于同一目录中,因此此路径应该有效。

现在创建者从外部进入 Modules/Objects 文件夹并添加一个名为 qmldir 的新文件(无扩展名)。用记事本之类的打开它并添加以下内容:

module Modules.Objects
MyObject 1.0 MyObject.qml

Re运行 qmake 并且您应该能够在 MainForm.ui.qml 中键入 "import Objects 1.0",不带引号。现在,如果你构建 运行 它应该像以前一样工作。

最后进入 Objects 文件夹并添加一个名为 designer 的文件夹。在设计器文件夹中添加一个名为 myobject.metainfo 的新文件。我认为名称并不重要,重要的是 .metainfo 部分。在其中放置以下内容:

MetaInfo {                                                       
   Type {                                             
      name: "Objects.MyObject"                                   
      icon: ""

      ItemLibraryEntry {
         name: "MyObject"
         category: "Objects"
         libraryIcon: ""
         version: "1.0"
         requiredImport: "Objects"

         QmlSource { source: "../MyObject.qml" }
      }
   }
}

现在,如果您在设计器中打开 MainForm.ui.qml,您可以从库窗格中拖放 MyObject!如果你这样做并使用文本编辑器查看 MainForm.ui.qml,你将实际看到创建的是 MyObjectForm{} 并且直到你手动重命名它以从名称中删除 "Form" 代码将不会构建并且运行成功;即使较早的并置拖放设法确定对象应该以 MyObject.qml (MyObject{}) 命名,而不是 MyObject.qml(MyObjectForm{}).

中的名称

所以
为什么使用 QtQuickUI 文件制作模块会搞砸命名方案?有任何想法吗?也许我错误地使用了 QtQuick,但是当文件并置时这一切都有效所以我要说我相信这一切都是可能的。

我通过删除 .metainfo 文件中的源字符串解决了这个问题。

对于关心我的人,我遵循了这些说明: http://doc.qt.io/qtcreator/creator-qml-modules-with-plugins.html 在第 5 步,当我在 Qt 文件夹中搜索 .metainfo 时,我选择了一个随机元信息文件,而不是他们专门选择的文件(qtcharts.metainfo vs qtquickcontrols2.metainfo)

qtcharts 可能用于某些其他类型的模块使用,其中指定源执行我不需要的操作,qtquickcontrols2 最终得到了我真正想要的语法。最终我找到了这个例子并发现删除源有效: https://forum.qt.io/topic/56207/how-to-load-custom-qml-controls-into-the-qml-designer