QR code scanner (QML component) (#9464)
Co-authored-by: Richard Ramos <info@richardramos.me>
This commit is contained in:
parent
eed98809d1
commit
7c1c178d37
|
@ -116,3 +116,6 @@
|
||||||
[submodule "vendor/nim-taskpools"]
|
[submodule "vendor/nim-taskpools"]
|
||||||
path = vendor/nim-taskpools
|
path = vendor/nim-taskpools
|
||||||
url = https://github.com/status-im/nim-taskpools.git
|
url = https://github.com/status-im/nim-taskpools.git
|
||||||
|
[submodule "ui/StatusQ/vendor/qzxing"]
|
||||||
|
path = ui/StatusQ/vendor/qzxing
|
||||||
|
url = https://github.com/status-im/qzxing.git
|
||||||
|
|
|
@ -37,5 +37,7 @@
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
<key>NSHighResolutionCapable</key>
|
<key>NSHighResolutionCapable</key>
|
||||||
<string>True</string>
|
<string>True</string>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>Scan QR codes</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -37,5 +37,7 @@
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
<key>NSHighResolutionCapable</key>
|
<key>NSHighResolutionCapable</key>
|
||||||
<string>True</string>
|
<string>True</string>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>Scan QR codes</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
14
Makefile
14
Makefile
|
@ -149,7 +149,7 @@ endif
|
||||||
|
|
||||||
MONITORING ?= false
|
MONITORING ?= false
|
||||||
ifneq ($(MONITORING), false)
|
ifneq ($(MONITORING), false)
|
||||||
DOTHERSIDE_CMAKE_PARAMS := ${DOTHERSIDE_CMAKE_PARAMS} -DMONITORING:BOOL=ON -DMONITORING_QML_ENTRY_POINT:STRING="/../monitoring/Main.qml"
|
DOTHERSIDE_CMAKE_PARAMS += -DMONITORING:BOOL=ON -DMONITORING_QML_ENTRY_POINT:STRING="/../monitoring/Main.qml"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,18 +175,23 @@ ifneq ($(detected_OS),Windows)
|
||||||
NIM_PARAMS += --passL:"-L$(QT5_LIBDIR)"
|
NIM_PARAMS += --passL:"-L$(QT5_LIBDIR)"
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
# We manually link QZXing to Nim application,
|
||||||
|
# because static libraries are not compiled into other static libraries (DOtherSide).
|
||||||
|
QZXING := vendor/DOtherSide/build/qzxing/libqzxing.a
|
||||||
DOTHERSIDE := vendor/DOtherSide/build/lib/libDOtherSideStatic.a
|
DOTHERSIDE := vendor/DOtherSide/build/lib/libDOtherSideStatic.a
|
||||||
DOTHERSIDE_CMAKE_PARAMS += -DENABLE_DYNAMIC_LIBS=OFF -DENABLE_STATIC_LIBS=ON
|
DOTHERSIDE_CMAKE_PARAMS += -DENABLE_DYNAMIC_LIBS=OFF -DENABLE_STATIC_LIBS=ON
|
||||||
# order matters here, due to "-Wl,-as-needed"
|
# order matters here, due to "-Wl,-as-needed"
|
||||||
NIM_PARAMS += --passL:"$(DOTHERSIDE)" --passL:"$(shell PKG_CONFIG_PATH="$(QT5_PCFILEDIR)" pkg-config --libs Qt5Core Qt5Qml Qt5Gui Qt5Quick Qt5QuickControls2 Qt5Widgets Qt5Svg Qt5Multimedia)"
|
NIM_PARAMS += --passL:"$(DOTHERSIDE)" --passL:"$(QZXING)" --passL:"$(shell PKG_CONFIG_PATH="$(QT5_PCFILEDIR)" pkg-config --libs Qt5Core Qt5Qml Qt5Gui Qt5Quick Qt5QuickControls2 Qt5Widgets Qt5Svg Qt5Multimedia)"
|
||||||
else
|
else
|
||||||
ifneq ($(QML_DEBUG), false)
|
ifneq ($(QML_DEBUG), false)
|
||||||
|
QZXING := vendor/DOtherSide/build/qzxing/Debug/qzxing.lib
|
||||||
DOTHERSIDE := vendor/DOtherSide/build/lib/Debug/DOtherSide.dll
|
DOTHERSIDE := vendor/DOtherSide/build/lib/Debug/DOtherSide.dll
|
||||||
else
|
else
|
||||||
|
QZXING := vendor/DOtherSide/build/qzxing/Release/qzxing.lib
|
||||||
DOTHERSIDE := vendor/DOtherSide/build/lib/Release/DOtherSide.dll
|
DOTHERSIDE := vendor/DOtherSide/build/lib/Release/DOtherSide.dll
|
||||||
endif
|
endif
|
||||||
DOTHERSIDE_CMAKE_PARAMS += -T"v141" -A x64 -DENABLE_DYNAMIC_LIBS=ON -DENABLE_STATIC_LIBS=OFF
|
DOTHERSIDE_CMAKE_PARAMS += -T"v141" -A x64 -DENABLE_DYNAMIC_LIBS=ON -DENABLE_STATIC_LIBS=OFF
|
||||||
NIM_PARAMS += -L:$(DOTHERSIDE)
|
NIM_PARAMS += -L:$(DOTHERSIDE) -L:$(QZXING)
|
||||||
NIM_EXTRA_PARAMS := --passL:"-lsetupapi -lhid"
|
NIM_EXTRA_PARAMS := --passL:"-lsetupapi -lhid"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -238,6 +243,9 @@ $(DOTHERSIDE): | deps
|
||||||
cmake $(DOTHERSIDE_CMAKE_PARAMS)\
|
cmake $(DOTHERSIDE_CMAKE_PARAMS)\
|
||||||
-DENABLE_DOCS=OFF \
|
-DENABLE_DOCS=OFF \
|
||||||
-DENABLE_TESTS=OFF \
|
-DENABLE_TESTS=OFF \
|
||||||
|
-DQZXING_USE_QML=ON \
|
||||||
|
-DQZXING_MULTIMEDIA=ON \
|
||||||
|
-DQZXING_USE_DECODER_QR_CODE=ON \
|
||||||
.. $(HANDLE_OUTPUT) && \
|
.. $(HANDLE_OUTPUT) && \
|
||||||
$(DOTHERSIDE_BUILD_CMD)
|
$(DOTHERSIDE_BUILD_CMD)
|
||||||
|
|
||||||
|
|
|
@ -13,5 +13,5 @@ docker run -it --rm \
|
||||||
-u jenkins:$(getent group $(whoami) | cut -d: -f3) \
|
-u jenkins:$(getent group $(whoami) | cut -d: -f3) \
|
||||||
-v "${PWD}:/status-desktop" \
|
-v "${PWD}:/status-desktop" \
|
||||||
-w /status-desktop \
|
-w /status-desktop \
|
||||||
statusteam/nim-status-client-build:1.2.0-qt5.15.2 \
|
statusteam/nim-status-client-build:1.2.1-qt5.15.2 \
|
||||||
./docker-linux-app-image.sh
|
./docker-linux-app-image.sh
|
||||||
|
|
|
@ -43,7 +43,7 @@ RUN apt update -yq && apt install -yq software-properties-common \
|
||||||
gnupg2 openssh-client ca-certificates locales sudo jq curl wget fuse s3cmd file llvm tk-dev xz-utils \
|
gnupg2 openssh-client ca-certificates locales sudo jq curl wget fuse s3cmd file llvm tk-dev xz-utils \
|
||||||
git make build-essential pkg-config cmake extra-cmake-modules gcc-9 g++-9 \
|
git make build-essential pkg-config cmake extra-cmake-modules gcc-9 g++-9 \
|
||||||
libgl1-mesa-dev libsm6 libice6 libfontconfig1 libdbus-1-3 libssl-dev libz-dev \
|
libgl1-mesa-dev libsm6 libice6 libfontconfig1 libdbus-1-3 libssl-dev libz-dev \
|
||||||
zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \
|
zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev unixodbc-dev libpq-dev \
|
||||||
libncurses5-dev libncursesw5-dev libpcsclite-dev libpcre3-dev libnss3 \
|
libncurses5-dev libncursesw5-dev libpcsclite-dev libpcre3-dev libnss3 \
|
||||||
gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
|
gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
|
||||||
gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-alsa libpulse-mainloop-glib0 \
|
gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-alsa libpulse-mainloop-glib0 \
|
||||||
|
|
|
@ -7,7 +7,7 @@ pipeline {
|
||||||
agent {
|
agent {
|
||||||
docker {
|
docker {
|
||||||
label 'linux'
|
label 'linux'
|
||||||
image 'statusteam/nim-status-client-build:1.2.0-qt5.15.2'
|
image 'statusteam/nim-status-client-build:1.2.1-qt5.15.2'
|
||||||
/* allows jenkins use cat and mounts '/dev/fuse' for linuxdeployqt */
|
/* allows jenkins use cat and mounts '/dev/fuse' for linuxdeployqt */
|
||||||
args '--entrypoint="" --cap-add SYS_ADMIN --security-opt apparmor:unconfined --device /dev/fuse'
|
args '--entrypoint="" --cap-add SYS_ADMIN --security-opt apparmor:unconfined --device /dev/fuse'
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ pipeline {
|
||||||
agent {
|
agent {
|
||||||
docker {
|
docker {
|
||||||
label 'linux'
|
label 'linux'
|
||||||
image 'statusteam/nim-status-client-build:1.2.0-qt5.15.2'
|
image 'statusteam/nim-status-client-build:1.2.1-qt5.15.2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
cp -R . ~/status-desktop
|
cp -R . ~/status-desktop
|
||||||
cd ~/status-desktop
|
cd ~/status-desktop
|
||||||
|
|
||||||
git clean -dfx && rm -rf vendor/* && make -j4 V=1 update
|
git clean -dfx && rm -rf vendor/* && git checkout vendor/DOtherSide && make -j4 V=1 update
|
||||||
make V=1 pkg
|
make V=1 pkg
|
||||||
|
|
||||||
# Make AppImage build accessible to the docker host
|
# Make AppImage build accessible to the docker host
|
||||||
|
|
|
@ -18,7 +18,7 @@ function check_version {
|
||||||
function install_build_dependencies {
|
function install_build_dependencies {
|
||||||
echo "Install build dependencies"
|
echo "Install build dependencies"
|
||||||
apt update
|
apt update
|
||||||
apt install -yq git build-essential pkg-config mesa-common-dev \
|
apt install -yq git build-essential pkg-config mesa-common-dev unixodbc-dev libpq-dev \
|
||||||
libglu1-mesa-dev wget libpcsclite-dev libpcre3-dev libssl-dev libpulse-mainloop-glib0 \
|
libglu1-mesa-dev wget libpcsclite-dev libpcre3-dev libssl-dev libpulse-mainloop-glib0 \
|
||||||
libxkbcommon-x11-dev extra-cmake-modules cmake
|
libxkbcommon-x11-dev extra-cmake-modules cmake
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,18 @@ set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
set(QZXING_USE_QML ON)
|
||||||
|
set(QZXING_MULTIMEDIA ON)
|
||||||
|
set(QZXING_USE_DECODER_QR_CODE ON)
|
||||||
|
|
||||||
# https://doc.qt.io/qtcreator/creator-qml-modules-with-plugins.html#importing-qml-modules
|
# https://doc.qt.io/qtcreator/creator-qml-modules-with-plugins.html#importing-qml-modules
|
||||||
set(QML_IMPORT_PATH
|
set(QML_IMPORT_PATH
|
||||||
${CMAKE_SOURCE_DIR}/src;${QML_IMPORT_PATH}
|
${CMAKE_SOURCE_DIR}/src;${QML_IMPORT_PATH}
|
||||||
CACHE STRING "")
|
CACHE STRING "")
|
||||||
|
|
||||||
|
|
||||||
add_subdirectory(vendor/SortFilterProxyModel)
|
add_subdirectory(vendor/SortFilterProxyModel)
|
||||||
|
add_subdirectory(vendor/qzxing/src)
|
||||||
add_subdirectory(sandbox)
|
add_subdirectory(sandbox)
|
||||||
add_subdirectory(sanity_checker)
|
add_subdirectory(sanity_checker)
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
|
|
|
@ -32,7 +32,8 @@ target_compile_definitions(${PROJECT_NAME}
|
||||||
PRIVATE SRC_DIR="${CMAKE_CURRENT_LIST_DIR}")
|
PRIVATE SRC_DIR="${CMAKE_CURRENT_LIST_DIR}")
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick Qt5::QuickControls2
|
${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick Qt5::QuickControls2
|
||||||
SortFilterProxyModel)
|
SortFilterProxyModel
|
||||||
|
qzxing)
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
find_library(AppKit AppKit)
|
find_library(AppKit AppKit)
|
||||||
|
|
|
@ -1198,6 +1198,17 @@ QtObject {
|
||||||
hasNotification: false
|
hasNotification: false
|
||||||
notificationsCount: 0
|
notificationsCount: 0
|
||||||
}
|
}
|
||||||
|
ListElement {
|
||||||
|
sectionId: "demoApp"
|
||||||
|
sectionType: 103
|
||||||
|
name: "QR Scanner"
|
||||||
|
active: false
|
||||||
|
image: ""
|
||||||
|
icon: "qr-scan"
|
||||||
|
color: ""
|
||||||
|
hasNotification: false
|
||||||
|
notificationsCount: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property ListModel demoAppSectionsModel: ListModel {
|
property ListModel demoAppSectionsModel: ListModel {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import QtGraphicalEffects 1.13
|
||||||
import QtQuick.Layouts 1.14
|
import QtQuick.Layouts 1.14
|
||||||
import Qt.labs.settings 1.0
|
import Qt.labs.settings 1.0
|
||||||
import QtQml.Models 2.14
|
import QtQml.Models 2.14
|
||||||
|
import QtMultimedia 5.14
|
||||||
|
|
||||||
import StatusQ 0.1
|
import StatusQ 0.1
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ StatusWindow {
|
||||||
readonly property int apiDocumentation: 100
|
readonly property int apiDocumentation: 100
|
||||||
readonly property int examples: 101
|
readonly property int examples: 101
|
||||||
readonly property int demoApp: 102
|
readonly property int demoApp: 102
|
||||||
|
readonly property int qrScanner: 103
|
||||||
}
|
}
|
||||||
|
|
||||||
function setActiveItem(sectionId) {
|
function setActiveItem(sectionId) {
|
||||||
|
@ -97,6 +99,10 @@ StatusWindow {
|
||||||
{
|
{
|
||||||
stackView.push(demoAppCmp)
|
stackView.push(demoAppCmp)
|
||||||
}
|
}
|
||||||
|
else if (model.sectionType === appSectionType.qrScanner)
|
||||||
|
{
|
||||||
|
stackView.push(qrScannerComponent)
|
||||||
|
}
|
||||||
rootWindow.setActiveItem(model.sectionId)
|
rootWindow.setActiveItem(model.sectionId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -537,6 +543,50 @@ StatusWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: qrScannerComponent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: Theme.palette.baseColor3
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 20
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
StatusQrCodeScanner {
|
||||||
|
id: qrScanner
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: width / sourceRatio
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
text: qsTr("Last tag: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusInput {
|
||||||
|
id: lastTagText
|
||||||
|
Layout.fillWidth: true
|
||||||
|
input.enabled: false
|
||||||
|
text: qrScanner.lastTag
|
||||||
|
input.rightPadding: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StatusMacTrafficLights {
|
StatusMacTrafficLights {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
|
@ -6,15 +6,17 @@
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
|
|
||||||
#include "StatusQ/typesregistration.h"
|
#include "StatusQ/typesregistration.h"
|
||||||
|
#include <QZXing.h>
|
||||||
|
|
||||||
SandboxApp::SandboxApp(int &argc, char **argv)
|
SandboxApp::SandboxApp(int &argc, char **argv)
|
||||||
: QGuiApplication(argc, argv)
|
: QGuiApplication(argc, argv)
|
||||||
{
|
{
|
||||||
|
QZXing::registerQMLTypes();
|
||||||
|
|
||||||
#ifdef QT_DEBUG
|
#ifdef QT_DEBUG
|
||||||
connect(&m_watcher, &QFileSystemWatcher::directoryChanged, [this](const QString&) {
|
connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, [this](const QString&) {
|
||||||
restartEngine();
|
restartEngine();
|
||||||
});
|
});
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ target_include_directories(${PROJECT_NAME} PUBLIC ${STATUSQ_DIR}/include)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick Qt5::QuickControls2
|
${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick Qt5::QuickControls2
|
||||||
SortFilterProxyModel)
|
SortFilterProxyModel
|
||||||
|
qzxing)
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
find_library(AppKit AppKit)
|
find_library(AppKit AppKit)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
|
|
||||||
#include "StatusQ/typesregistration.h"
|
#include "StatusQ/typesregistration.h"
|
||||||
|
#include <QZXing>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -16,6 +17,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
engine.addImportPath(QStringLiteral(":/"));
|
engine.addImportPath(QStringLiteral(":/"));
|
||||||
|
|
||||||
|
QZXing::registerQMLTypes();
|
||||||
|
|
||||||
QDirIterator it(":", QDirIterator::Subdirectories);
|
QDirIterator it(":", QDirIterator::Subdirectories);
|
||||||
bool errorsFound = false;
|
bool errorsFound = false;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
|
import QtMultimedia 5.15
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
|
||||||
|
import QZXing 3.3
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property alias camera: camera
|
||||||
|
|
||||||
|
readonly property size sourceSize: Qt.size(videoOutput.sourceRect.width, videoOutput.sourceRect.height)
|
||||||
|
readonly property size contentSize: Qt.size(videoOutput.contentRect.width, videoOutput.contentRect.height)
|
||||||
|
readonly property real sourceRatio: videoOutput.sourceRect.width / videoOutput.sourceRect.height
|
||||||
|
|
||||||
|
property int failsCount: 0
|
||||||
|
property int tagsCount: 0
|
||||||
|
property int decodeTime: 0
|
||||||
|
|
||||||
|
property string lastTag
|
||||||
|
|
||||||
|
implicitWidth: sourceSize.width
|
||||||
|
implicitHeight: sourceSize.height
|
||||||
|
|
||||||
|
signal tagFound(string tag)
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
|
||||||
|
readonly property int radius: 16
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera {
|
||||||
|
id: camera
|
||||||
|
captureMode: Camera.CaptureVideo
|
||||||
|
focus {
|
||||||
|
focusMode: CameraFocus.FocusContinuous
|
||||||
|
focusPointMode: CameraFocus.FocusPointAuto
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: Theme.palette.baseColor4
|
||||||
|
radius: d.radius
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
implicitWidth: videoOutput.contentRect.width
|
||||||
|
implicitHeight: videoOutput.contentRect.height
|
||||||
|
visible: camera.availability === Camera.Available
|
||||||
|
|
||||||
|
VideoOutput {
|
||||||
|
id: videoOutput
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
source: camera
|
||||||
|
filters: [ qzxingFilter ]
|
||||||
|
fillMode: VideoOutput.PreserveAspectFit
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: mask
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: 16
|
||||||
|
visible: false
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
|
||||||
|
OpacityMask {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: videoOutput
|
||||||
|
maskSource: mask
|
||||||
|
}
|
||||||
|
|
||||||
|
QZXingFilter {
|
||||||
|
id: qzxingFilter
|
||||||
|
orientation: videoOutput.orientation
|
||||||
|
captureRect: {
|
||||||
|
videoOutput.contentRect; videoOutput.sourceRect; // bindings
|
||||||
|
const normalizedRectangle = Qt.rect(0, 0, 1, 1)
|
||||||
|
const rectangle = videoOutput.mapNormalizedRectToItem(normalizedRectangle)
|
||||||
|
return videoOutput.mapRectToSource(rectangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder {
|
||||||
|
enabledDecoders: QZXing.DecoderFormat_QR_CODE
|
||||||
|
tryHarder: true
|
||||||
|
onTagFound: {
|
||||||
|
root.lastTag = tag
|
||||||
|
root.tagFound(tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDecodingFinished: {
|
||||||
|
if (succeeded)
|
||||||
|
++root.tagsCount
|
||||||
|
else
|
||||||
|
++root.failsCount
|
||||||
|
root.decodeTime = decodeTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement camera selector
|
||||||
|
// For me it works once. The first switch between 2 cameras is ok.
|
||||||
|
// The second switch doesn't work and behaves different with 2 approaches:
|
||||||
|
// With standard `ComboBox` it throws an exception.
|
||||||
|
// Width `StatusComboBox` it just kinda unbinds from the Camera.
|
||||||
|
//
|
||||||
|
// ComboBox {
|
||||||
|
// id: cameraComboBox
|
||||||
|
|
||||||
|
// anchors {
|
||||||
|
// right: parent.right
|
||||||
|
// bottom: parent.bottom
|
||||||
|
// margins: 10
|
||||||
|
// }
|
||||||
|
|
||||||
|
// width: implicitWidth
|
||||||
|
// opacity: 0.7
|
||||||
|
// model: QtMultimedia.availableCameras
|
||||||
|
// textRole: "displayName"
|
||||||
|
// valueRole: "deviceId"
|
||||||
|
// onCurrentValueChanged: {
|
||||||
|
// camera.deviceId = currentValue
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// StatusComboBox {
|
||||||
|
// id: cameraComboBox
|
||||||
|
// anchors {
|
||||||
|
// right: parent.right
|
||||||
|
// bottom: parent.bottom
|
||||||
|
// margins: 10
|
||||||
|
// }
|
||||||
|
|
||||||
|
// width: implicitWidth
|
||||||
|
// opacity: 0.7
|
||||||
|
// model: QtMultimedia.availableCameras
|
||||||
|
// control.textRole: "displayName"
|
||||||
|
// control.valueRole: "deviceId"
|
||||||
|
// onCurrentValueChanged: {
|
||||||
|
// console.log("setting deviceId to", currentValue)
|
||||||
|
// camera.deviceId = currentValue
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: Theme.palette.dangerColor1
|
||||||
|
visible: camera.availability !== Camera.Available
|
||||||
|
text: qsTr("Camera is not available")
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: Theme.palette.directColor5
|
||||||
|
visible: camera.errorCode !== Camera.NoError
|
||||||
|
text: "Error comes here" // camera.errorString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -49,3 +49,4 @@ StatusChart 0.1 StatusChart.qml
|
||||||
StatusChartPanel 0.1 StatusChartPanel.qml
|
StatusChartPanel 0.1 StatusChartPanel.qml
|
||||||
StatusStepper 0.1 StatusStepper.qml
|
StatusStepper 0.1 StatusStepper.qml
|
||||||
LoadingComponent 0.1 LoadingComponent.qml
|
LoadingComponent 0.1 LoadingComponent.qml
|
||||||
|
StatusQrCodeScanner 0.1 StatusQrCodeScanner.qml
|
||||||
|
|
|
@ -196,5 +196,6 @@
|
||||||
<file>StatusQ/Core/Utils/ModelUtils.qml</file>
|
<file>StatusQ/Core/Utils/ModelUtils.qml</file>
|
||||||
<file>StatusQ/Core/Utils/ModelsComparator.qml</file>
|
<file>StatusQ/Core/Utils/ModelsComparator.qml</file>
|
||||||
<file>StatusQ/Core/Utils/ModelChangeTracker.qml</file>
|
<file>StatusQ/Core/Utils/ModelChangeTracker.qml</file>
|
||||||
|
<file>StatusQ/Components/StatusQrCodeScanner.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 80bb1d21903881e4061a41739d413a296ceb3b49
|
|
@ -28,6 +28,7 @@ if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(../../ui/StatusQ/vendor/qzxing/src qzxing)
|
||||||
add_subdirectory(../../ui/StatusQ/vendor/SortFilterProxyModel SortFilterProxyModel)
|
add_subdirectory(../../ui/StatusQ/vendor/SortFilterProxyModel SortFilterProxyModel)
|
||||||
add_subdirectory(lib)
|
add_subdirectory(lib)
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ macro(add_target name type)
|
||||||
|
|
||||||
target_include_directories(${name} PUBLIC include include/Qt ${STATUSQ_DIR}/include)
|
target_include_directories(${name} PUBLIC include include/Qt ${STATUSQ_DIR}/include)
|
||||||
|
|
||||||
target_link_libraries(${name} PRIVATE Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Qml Qt5::Quick Qt5::Network Qt5::Multimedia SortFilterProxyModel)
|
target_link_libraries(${name} PRIVATE Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Qml Qt5::Quick Qt5::Network Qt5::Multimedia SortFilterProxyModel qzxing)
|
||||||
|
|
||||||
target_compile_definitions(${name} PRIVATE $<$<CONFIG:Debug>:QT_QML_DEBUG>)
|
target_compile_definitions(${name} PRIVATE $<$<CONFIG:Debug>:QT_QML_DEBUG>)
|
||||||
if(DEFINED QML_DEBUG_PORT)
|
if(DEFINED QML_DEBUG_PORT)
|
||||||
|
@ -53,7 +53,7 @@ macro(add_target name type)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# for DOtherSide.pc
|
# for DOtherSide.pc
|
||||||
set(PC_REQUIRES "Qt5Core, Qt5Gui, Qt5Widgets, Qt5Qml, Qt5Quick, Qt5Network, Qt5DBus, Qt5Multimedia, SortFilterProxyModel")
|
set(PC_REQUIRES "Qt5Core, Qt5Gui, Qt5Widgets, Qt5Qml, Qt5Quick, Qt5Network, Qt5DBus, Qt5Multimedia, SortFilterProxyModel, qzxing")
|
||||||
if (${Qt5QuickControls2_FOUND})
|
if (${Qt5QuickControls2_FOUND})
|
||||||
target_link_libraries(${name} PRIVATE Qt5::QuickControls2)
|
target_link_libraries(${name} PRIVATE Qt5::QuickControls2)
|
||||||
set(PC_REQUIRES "${PC_REQUIRES}, Qt5QuickControls2")
|
set(PC_REQUIRES "${PC_REQUIRES}, Qt5QuickControls2")
|
||||||
|
|
|
@ -85,6 +85,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <qqmlsortfilterproxymodeltypes.h>
|
#include <qqmlsortfilterproxymodeltypes.h>
|
||||||
|
#include <QZXing.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -103,6 +104,7 @@ void register_meta_types()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qqsfpm::registerTypes();
|
qqsfpm::registerTypes();
|
||||||
|
QZXing::registerQMLTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue