У меня есть проект, который использует функцию сервера / клиента. Макет моего проекта:
- Проект с подпроектами
- -сервер
- --- некоторые файлы (не важно)
- -клиент отображения
- --- Display.qml -> Main view
- --- ViewerForm.ui.qml -> UI Отображение для создания представления
- --- Viewer.qml -> Для запуска нажатий кнопок и JavaScript
Я могу запустить сервер и клиент без проблем. Теперь я хотел бы, чтобы Viewer
и ViewerForm
были доступны для различных приложений. Например:
- Автономное клиентское приложение (только отображение клиента)
- Импортировано в другое приложение, которое может иметь несколько типов страниц пользовательского интерфейса, в которых одно является отображением клиента.
Как это настроить, чтобы у меня был только проект 1 Viewer
, и его можно было импортировать в разные приложения. Должен ли это быть плагин Qt? Модуль? Я посмотрел документацию Qt и создал проект ViewerPlugin
как собственный проект с ViewerForm.ui.qml
, Viewer.qml
, несколькими компонентными файлами *.ui.qml
и *.qml
и файлами javascript, как показанониже. Когда я собираю ViewerPlugin
, он создает папку Viewer
с файлами: ViewerPlugin.dll
, ViewerPlugin.exp
, ViewerPlugin.lib
и qmldir
. Затем я копирую эту папку в свое клиентское приложение и импортирую подключаемый модуль QML в мой файл Display.qml, например import Viewer 1.0
. Но я получаю ошибки сборки, которые он не может найти: CListView.qml и другие файлы qml.
viewerplugin.pro
TEMPLATE = lib
TARGET = ViewerPlugin
QT += qml quick
CONFIG += qt plugin c++11
DESTDIR = ../../imports/Viewer
TARGET = $$qtLibraryTarget($$TARGET)
uri = Viewer
# Input
SOURCES += \
viewerplugin_plugin.cpp \
viewer.cpp
HEADERS += \
viewerplugin_plugin.h \
viewer.h
DISTFILES += qmldir \
Viewer.qml \
ViewerForm.ui.qml \
components/CListView.qml \
components/CListViewForm.ui.qml \
components/CRangeSliderForm.ui.qml \
components/CSliderForm.ui.qml \
components/IconButtonForm.ui.qml \
components/PressAndHoldButton.qml \
components/TextButton.qml
RESOURCES += qml.qrc
!equals(_PRO_FILE_PWD_, $$OUT_PWD) {
copy_qmldir.target = $$OUT_PWD/qmldir
copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir
copy_qmldir.commands = $(COPY_FILE) "$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)" "$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)"
QMAKE_EXTRA_TARGETS += copy_qmldir
PRE_TARGETDEPS += $$copy_qmldir.target
}
qmldir.files = qmldir
# Copy the qmldir file to the same folder as the plugin binary
cpqmldir.files = qmldir
cpqmldir.path = $$DESTDIR
COPIES += cpqmldir
qml.qrc
<RCC>
<qresource prefix="/">
<file alias="ViewerForm.ui.qml">ViewerForm.ui.qml</file>
</qresource>
<qresource prefix="/components">
<file alias="IconButtonForm.ui.qml">components/IconButtonForm.ui.qml</file>
<file alias="CRangeSliderForm.ui.qml">components/CRangeSliderForm.ui.qml</file>
<file alias="CSliderForm.ui.qml">components/CSliderForm.ui.qml</file>
<file alias="CListView.qml">components/CListView.qml</file>
<file alias="TextButton.qml">components/TextButton.qml</file>
</qresource>
<qresource prefix="/HTML5">
<file alias="index.html">HTML5/index.html</file>
<file alias="loader.css">HTML5/loader.css</file>
</qresource>
<qresource prefix="/resources">
<file alias="fontawesome-webfont.ttf">resources/fontawesome-webfont.ttf</file>
</qresource>
</RCC>
qmldir
module Viewer
CListView 1.0 CListView.qml
CListViewForm 1.0 CListViewForm.ui.qml
CRangeSliderForm 1.0 CRangeSliderForm.ui.qml
CSliderForm 1.0 CSliderForm.ui.qml
IconButtonForm 1.0 IconButtonForm.ui.qml
PressAndHoldButton 1.0 PressAndHoldButton.qml
TextButton 1.0 TextButton.qml
plugin ViewerPlugin
Компоненты и папки HTML5 существуют, как описано в файле .pro
. viewerplugin_plugin.h/cpp
и viewer.h/cpp
- это основные файлы, созданные с помощью мастера Qt5 для расширений QT для расширения QQmlExtensionPlugin
.
Ниже приведены файлы, которые пытаются импортировать ViewerPlugin:
Client.pro
QT += quick qml serialport core webengine webchannel
CONFIG += c++11 qt
CONFIG += qtquickcompiler
RESOURCES += qml.qrc
!include($${top_srcdir}/common/common.pri) {
error("Couldn't find common.pri file")
}
!include($${top_srcdir}/qmake-target-platform.pri) {
error("Couldn't find qmake-target-platform.pri file")
}
!include($${top_srcdir}/qmake-destination-path.pri) {
error("Couldn't find qmake-destination-path.pri file")
}
SOURCES += \
main.cpp
DESTDIR = $${top_srcdir}/binaries/$$DESTINATION_PATH
OBJECTS_DIR = $${top_srcdir}/build/$$DESTINATION_PATH/.obj
MOC_DIR = $${top_srcdir}/build/$$DESTINATION_PATH/.moc
RCC_DIR = $${top_srcdir}/build/$$DESTINATION_PATH/.qrc
UI_DIR = $${top_srcdir}/build/$$DESTINATION_PATH/.ui
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Refer to the documentation for the
# deprecated API to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
DISTFILES += \
Display.qml
# ViewerPlugin needs to be copied to binaries executable directory
CONFIG += file_copies
COPIES += ViewerPlugin
ViewerPlugin.files = $$files($${Viewer}/*)
ViewerPlugin.path = $${DESTDIR}/Viewer
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH = ${top_srcdir}
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
qml.qrc
<RCC>
<qresource prefix="/">
<file alias="Display.qml">Display.qml</file>
</qresource>
</RCC>
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtWebEngine>
#include <QObject>
#include <QMetaObject>
int main(int argc, char *argv[])
{
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QtWebEngine::initialize();
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/Display.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
Display.qml
import Viewer 1.0
ApplicationWindow {
id: window
visibility: "Maximized"
visible: true
ViewerForm {
id: viewer
}