web-dev-qa-db-ja.com

Qt5 QMLモジュールがインストールされていません

Qt QMLのモジュールについて混乱しています。私はすべてのドキュメントを読みましたが、いくつかの基本的なアイデアを明確にしません。

多数のQMLファイルをディレクトリに配置し、qmldirファイルを追加して、特定されたモジュールを記述することができることを理解しています。これを実行してQML_IMPORT_PATHを調整すると、QtCreatorが満足し、インポートModuleName 1.0行の下線が止まります。

作成者は幸せですが、機能しません。モジュールがインストールされていません。私の質問は次のとおりです。

  • 「インストール済み」とはどういう意味ですか。ファイルのディレクトリはありますが、どこにも「インストール」していません。
  • モジュールをビルド/コンパイルしてDLL/.soを作成する必要がありますか?
  • モジュールのQMLファイルはメインアプリのリソースに入りますか、それ以外の場合はどこにありますか?
  • 私のmain.qmlファイルはアプリリソースの一部です。実行時にアプリがモジュールのリソースを見つける方法.

これらの質問はすべて申し訳ありませんが、これらのモジュールの基本は明確ではありません。 「モジュール」が単なるファイルの共有なのか、それともコンパイルされたユニットなのかわかりません。

助けてくれてありがとう。

13
jkj yuio

私はあなたの質問に答えようとします:

  • installedは適切なパスに配置されていることを意味すると思う
    実行時に見つけることができること
  • そのために必ずしもQmlExtrensionPluginを作成/構築する必要はありません。また、このモジュールを記述するqmldirを使用して、1つのディレクトリ内のプレーンなQMLファイルをモジュールとして使用することもできます。コードを配布することです-コードを非表示にする場合は、QmlExtensionPluginを使用して、コンパイルされたモジュールを提供します。
  • モジュールはリソースシステム内にある場合も、ディスク上のファイルとして存在する場合もあります。
  • アプリは事前定義されたパスでモジュールを探します-アプリのディレクトリ、QTプラグインパス、QML2_IMPORT_PATH、engine->addImportPath()を使用して追加したディレクトリ

モジュールがロードされないことにつながる可能性のあるものがたくさんあります。以下を確認できます。

  1. Qmldirのモジュール識別子は、モジュールが実際に存在するディレクトリ名と同じである必要があります。たとえば、モジュールのモジュール識別子がqmldirにmodule TestModuleである場合、モジュールのディレクトリ名はTestModuleでなければなりません。
  2. QML拡張プラグイン(共有ライブラリ)の場合、プラグインのディレクトリ名がプラグインの名前と同じであることを確認してください。
  3. QML2_IMPORT_PATH(名前に2があることを確認してください)モジュールを含むディレクトリを指すenv変数をエクスポートします。リストにディレクトリを追加してプラグインを検索するQQmlEngine::addImportPathメソッドもあります。
  4. Qml拡張プラグイン(共有ライブラリ)の場合、依存関係が欠落している可能性があります。 Windowsでは Dependency Walker で、Linuxではlddコマンドで確認できます。
  5. QT_PLUGIN_PATHランタイム変数を設定すると、プラグインのロードに役立つ場合があります。プラグインのディレクトリ自体ではなく、プラグインのディレクトリを含むディレクトリを指す必要があります。
  6. 問題をよりよく理解するために、プラグインがロードされている間にトレースを有効にして、トレースを有効にすることもできます-QT_DEBUG_PLUGINS=1およびQML_IMPORT_TRACE=1環境変数をエクスポートします

このリンクを読むこともできます: https://doc.qt.io/qt-5/qtqml-modules-identifiedmodules.html

9
rightaway717

私の場合(qrcリソースにすべてのQMLファイルがあります)、qmldirをリソースにも追加し、QQmlApplicationEngineのメソッドaddImportPath( "qrc:/")を呼び出しました。

私のmain.cppは次のようになります:

QQmlApplicationEngine engine;
engine.addImportPath("qrc:/");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

.proファイルの重要な部分は次のようになります。

RESOURCES += qml.qrc \
    MyModule/mymodule.qrc

QML_IMPORT_PATH += $$PWD

私のqmldir:

module MyModule

MyItem          2.0 MyItem20.qml
MyItem          2.1 MyItem21.qml

私のqrc:

<RCC>
    <qresource prefix="/MyModule">
        <file>MyItem20.qml</file>
        <file>MyItem21.qml</file>
        <file>qmldir</file>
    </qresource>
</RCC>

そして最後に私のmain.qml:

import QtQuick 2.5
import QtQuick.Window 2.2

import MyModule 2.0

Window {
    visible: true
    width: 640
    height: 480

    MyItem {
        anchors.fill: parent
    }
}

QtCreatorは喜んで(コンポーネントとインポートに下線を引かない)、モジュールがロードされます。お役に立てれば。

8
arxarian

arxarian's answer -モジュールを統合するための最良の手法だと思う-に拡張したいが、コメントにそれらの考えを収めることができなかったので、ここに新しい答えがあります。

Qmlモジュールとその関連リソースはランタイムエンティティであり、アプリケーションリソースに含まれていない限り、実行可能ファイルに対して相対的な場所に個別に存在すると想定されることを最初に理解することが重要です。それらをリソースに含めることで、それらはまだランタイムエンティティですが、アプリケーションバイナリ内のqrc:/ルートパスの下に存在します。このモジュールの非表示は、展開後にモジュールを開いたり、プリコンパイルされたプラグインとして個別に展開したりする必要がない限り(つまり、動的にリンクされた図書館)。

arxarianの答え の重要な要素の説明は次のとおりです。

  1. engine.addImportPath("qrc:/");は、アプリケーションリソースストレージでqmlモジュールを探すようにエンジンに指示するために、qmlをロードする前にC++コードで必要です。
  2. モジュールのファイルを アプリケーションリソースストレージ に追加するには、プロジェクトファイル(.pro)にRESOURCES += MyModule/mymodule.qrcが必要です。
  3. プロジェクトファイルのQML_IMPORT_PATH += $$PWDは、Qt Creatorにプロジェクトソースツリーのルートから始まるモジュールを探すように指示します。私の場合、モジュールディレクトリがそこから始まったため、これをサブディレクトリ(たとえば、「ui/modules」)に設定する必要がありました。インポートパスには、すべてのモジュールディレクトリの下にルートが含まれている必要があります。私が知る限り、この命令はQt Creatorのみを対象としており、IDE=ビルドには影響しません。そのため、#1が必要です。
  4. Qmldirファイルの内容はそのまま すべてのqmlモジュールの標準 ですが、モジュールの.qrcリソースファイルに含めるのは、ランタイムストレージで何が起こっているかを考えるまで直感的ではありません。エンジンが実行時にそれを見つけてモジュールを定義できるように、アプリケーションリソースストレージに含まれるように.qrcにある必要があります。モジュールの.qrcファイル内の<qresource prefix="/MyModule">は、アプリケーションリソースストレージのqrc:/ルートに関連するモジュールサブディレクトリを定義します。
  5. Qmlのimport MyModule <version>ステートメントが成功するように設定されました。起動時に、エンジンはqrc:/の下のディレクトリにモジュールを配置し、そこにあるqmldirファイルを解析してモジュールを定義し、それらのエントリから名前とバージョンを確立します。

うまくいけば、これは他の人が何が起こっているのかを理解するのに役立ち、私が何かを誤解したかどうか教えてください。

4
Travis R

同様の問題には少し時間がかかったので、次の人の手間を省くためにここに投稿するだけです。

私の問題は、目に見えないキャラクターがモジュール名に潜入したことです。おそらくコピー&ペーストで。ここに私の問題:

エラー出力の例:

MyEngine failed to load component
qrc:/qml/main.qml:53 Type MyComponent unavailable
file:///Users/<pathToProject>/MyProject/qml/MyModule/MyComponent.qml:-1 No such file or directory

それはすべて正常に見え、表示されるパスは確かに正しいものです。それで何が悪いのでしょうか?

次に、そのパスをターミナルウィンドウにコピーします。

file:///Users/<pathToProject>/MyProject/qml/MyModule/<feff>MyComponent.qml

それがあります:

"<feff>"

Qmldirファイルでコンポーネント名を手動で再入力し、非表示の文字を効果的に削除することで問題を解決しました。

0
Tony