adapt for qt5.
This commit is contained in:
parent
d822dcda76
commit
66c187ed1c
17
AntiClipSettings.qrc
Normal file
17
AntiClipSettings.qrc
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/qt/qml/AntiClipSettings">
|
||||||
|
<file>qml/DataCollectionPopup.qml</file>
|
||||||
|
<file>qml/DeviceView.qml</file>
|
||||||
|
<file>qml/IconButton.qml</file>
|
||||||
|
<file>qml/IpTextField.qml</file>
|
||||||
|
<file>qml/Main.qml</file>
|
||||||
|
<file>qml/MessageDialog.qml</file>
|
||||||
|
<file>qml/NetworkSettingPopup.qml</file>
|
||||||
|
<file>qml/OtaPopup.qml</file>
|
||||||
|
<file>qml/StatusTip.qml</file>
|
||||||
|
<file>resources/popup_close.svg</file>
|
||||||
|
<file>resources/prompt_delete.svg</file>
|
||||||
|
<file>resources/successfull.svg</file>
|
||||||
|
<file>resources/warning.svg</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
@ -7,6 +7,7 @@
|
|||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
|
#include <QQmlContext>
|
||||||
|
|
||||||
Application::Application(int &argc, char **argv)
|
Application::Application(int &argc, char **argv)
|
||||||
: m_app(std::make_shared<QGuiApplication>(argc, argv)), m_videoFrameProvider(new VideoFrameProvider()),
|
: m_app(std::make_shared<QGuiApplication>(argc, argv)), m_videoFrameProvider(new VideoFrameProvider()),
|
||||||
@ -281,10 +282,19 @@ void Application::onDeviceDisconnected() {
|
|||||||
int Application::exec() {
|
int Application::exec() {
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
engine.addImageProvider("videoframe", m_videoFrameProvider);
|
engine.addImageProvider("videoframe", m_videoFrameProvider);
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
&engine, &QQmlApplicationEngine::objectCreationFailed, this, []() { QCoreApplication::exit(-1); },
|
&engine, &QQmlApplicationEngine::objectCreationFailed, this, []() { QCoreApplication::exit(-1); },
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
engine.loadFromModule("AntiClipSettings", "Main");
|
engine.loadFromModule("AntiClipSettings", "Main");
|
||||||
|
#else
|
||||||
|
qmlRegisterSingletonInstance("AntiClipSettings", 1, 0, "App", this);
|
||||||
|
qmlRegisterUncreatableType<DeviceConnection>("AntiClipSettings", 1, 0, "DeviceConnection",
|
||||||
|
"Only created in C++...");
|
||||||
|
engine.load("qrc:/qt/qml/AntiClipSettings/qml/Main.qml");
|
||||||
|
#endif
|
||||||
|
bool isQt5 = (QT_VERSION < QT_VERSION_CHECK(6, 0, 0));
|
||||||
|
engine.rootContext()->setContextProperty("isQt5", isQt5);
|
||||||
return m_app->exec();
|
return m_app->exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,7 +303,9 @@ Application *Application::create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) {
|
|||||||
auto app = Amass::Singleton<Application>::instance();
|
auto app = Amass::Singleton<Application>::instance();
|
||||||
if (app) {
|
if (app) {
|
||||||
ret = app.get();
|
ret = app.get();
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
QJSEngine::setObjectOwnership(ret, QJSEngine::CppOwnership);
|
QJSEngine::setObjectOwnership(ret, QJSEngine::CppOwnership);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
project(AntiClipSettings VERSION 0.1 LANGUAGES C CXX)
|
project(AntiClipSettings VERSION 0.1 LANGUAGES C CXX)
|
||||||
set(APPLICATION_NAME "T009上位机")
|
set(APPLICATION_NAME "T009")
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
@ -9,21 +9,28 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||||||
set(Projects_ROOT E:/Projects)
|
set(Projects_ROOT E:/Projects)
|
||||||
set(Libraries_ROOT ${Projects_ROOT}/Libraries)
|
set(Libraries_ROOT ${Projects_ROOT}/Libraries)
|
||||||
|
|
||||||
set(BOOST_ROOT ${Libraries_ROOT}/boost_1_86_0_msvc2022_64bit)
|
if (Qt6_FOUND)
|
||||||
set(Boost_INCLUDE_DIR ${BOOST_ROOT}/include/boost-1_86)
|
qt_standard_project_setup(REQUIRES 6.5)
|
||||||
|
set(BOOST_ROOT ${Libraries_ROOT}/boost_1_86_0_msvc2022_64bit)
|
||||||
|
set(Boost_INCLUDE_DIR ${BOOST_ROOT}/include/boost-1_86)
|
||||||
|
add_compile_definitions(
|
||||||
|
BOOST_USE_WINAPI_VERSION=BOOST_WINAPI_VERSION_WIN10
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
set(BOOST_ROOT ${Libraries_ROOT}/boost_1_83_0_msvc2022_64bit)
|
||||||
|
set(Boost_INCLUDE_DIR ${BOOST_ROOT}/include/boost-1_83)
|
||||||
|
endif()
|
||||||
option(Boost_USE_STATIC_LIBS OFF)
|
option(Boost_USE_STATIC_LIBS OFF)
|
||||||
add_compile_definitions(
|
|
||||||
BOOST_USE_WINAPI_VERSION=BOOST_WINAPI_VERSION_WIN10
|
|
||||||
)
|
|
||||||
|
|
||||||
set(FFmpeg_ROOT ${Libraries_ROOT}/ffmpeg-6.1.1-full_build-shared)
|
set(FFmpeg_ROOT ${Libraries_ROOT}/ffmpeg-6.1.1-full_build-shared)
|
||||||
set(FFmpeg_INCLUDE_DIR ${FFmpeg_ROOT}/include)
|
set(FFmpeg_INCLUDE_DIR ${FFmpeg_ROOT}/include)
|
||||||
set(FFmpeg_LIB_DIR ${FFmpeg_ROOT}/lib)
|
set(FFmpeg_LIB_DIR ${FFmpeg_ROOT}/lib)
|
||||||
|
|
||||||
find_package(Boost REQUIRED COMPONENTS json)
|
find_package(Boost REQUIRED COMPONENTS json)
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Qml Quick Network QuickControls2)
|
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Qml Quick Network QuickControls2)
|
||||||
|
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Qml Quick Network QuickControls2)
|
||||||
qt_standard_project_setup(REQUIRES 6.5)
|
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND D:/msys64/usr/bin/git rev-parse --short HEAD
|
COMMAND D:/msys64/usr/bin/git rev-parse --short HEAD
|
||||||
@ -32,8 +39,8 @@ execute_process(
|
|||||||
)
|
)
|
||||||
configure_file(Configuration.h.in Configuration.h)
|
configure_file(Configuration.h.in Configuration.h)
|
||||||
|
|
||||||
qt_add_executable(AntiClipSettings
|
add_executable(AntiClipSettings
|
||||||
AntiClipSettings.rc
|
AntiClipSettings.rc AntiClipSettings.qrc
|
||||||
main.cpp
|
main.cpp
|
||||||
Application.h Application.cpp
|
Application.h Application.cpp
|
||||||
DataStructure.h
|
DataStructure.h
|
||||||
@ -44,8 +51,10 @@ qt_add_executable(AntiClipSettings
|
|||||||
VideoFrameProvider.h VideoFrameProvider.cpp
|
VideoFrameProvider.h VideoFrameProvider.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (Qt6_FOUND)
|
||||||
qt_add_qml_module(AntiClipSettings
|
qt_add_qml_module(AntiClipSettings
|
||||||
URI AntiClipSettings
|
URI AntiClipSettings
|
||||||
|
VERSION 1.0
|
||||||
QML_FILES
|
QML_FILES
|
||||||
qml/Main.qml
|
qml/Main.qml
|
||||||
qml/DeviceView.qml
|
qml/DeviceView.qml
|
||||||
@ -62,6 +71,7 @@ qt_add_qml_module(AntiClipSettings
|
|||||||
resources/successfull.svg
|
resources/successfull.svg
|
||||||
resources/warning.svg
|
resources/warning.svg
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
|
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
|
||||||
# If you are developing for iOS or macOS you should consider setting an
|
# If you are developing for iOS or macOS you should consider setting an
|
||||||
@ -87,10 +97,10 @@ target_link_directories(AntiClipSettings
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(AntiClipSettings
|
target_link_libraries(AntiClipSettings
|
||||||
PRIVATE Qt6::Qml
|
PRIVATE Qt${QT_VERSION_MAJOR}::Qml
|
||||||
PRIVATE Qt6::Quick
|
PRIVATE Qt${QT_VERSION_MAJOR}::Quick
|
||||||
PRIVATE Qt6::QuickControls2
|
PRIVATE Qt${QT_VERSION_MAJOR}::QuickControls2
|
||||||
PRIVATE Qt6::Network
|
PRIVATE Qt${QT_VERSION_MAJOR}::Network
|
||||||
PRIVATE Boost::json
|
PRIVATE Boost::json
|
||||||
PRIVATE avcodec
|
PRIVATE avcodec
|
||||||
PRIVATE swscale
|
PRIVATE swscale
|
||||||
@ -99,6 +109,7 @@ target_link_libraries(AntiClipSettings
|
|||||||
PRIVATE avformat
|
PRIVATE avformat
|
||||||
PRIVATE Universal
|
PRIVATE Universal
|
||||||
PRIVATE Encrypt
|
PRIVATE Encrypt
|
||||||
|
PRIVATE Ws2_32
|
||||||
)
|
)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
@ -108,11 +119,13 @@ install(TARGETS AntiClipSettings
|
|||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_generate_deploy_qml_app_script(
|
if (Qt6_FOUND)
|
||||||
TARGET AntiClipSettings
|
qt_generate_deploy_qml_app_script(
|
||||||
OUTPUT_SCRIPT deploy_script
|
TARGET AntiClipSettings
|
||||||
MACOS_BUNDLE_POST_BUILD
|
OUTPUT_SCRIPT deploy_script
|
||||||
NO_UNSUPPORTED_PLATFORM_ERROR
|
MACOS_BUNDLE_POST_BUILD
|
||||||
DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM
|
NO_UNSUPPORTED_PLATFORM_ERROR
|
||||||
)
|
DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM
|
||||||
install(SCRIPT ${deploy_script})
|
)
|
||||||
|
install(SCRIPT ${deploy_script})
|
||||||
|
endif()
|
||||||
|
@ -523,6 +523,11 @@ QString DeviceConnection::handleCommand(const std::string_view &replyText, const
|
|||||||
m_otaTimer = new QTimer(this);
|
m_otaTimer = new QTimer(this);
|
||||||
m_otaTimer->setSingleShot(true);
|
m_otaTimer->setSingleShot(true);
|
||||||
}
|
}
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
Qt::ConnectionType type = Qt::SingleShotConnection;
|
||||||
|
#else
|
||||||
|
Qt::ConnectionType type = Qt::UniqueConnection;
|
||||||
|
#endif
|
||||||
m_otaTimer->callOnTimeout(
|
m_otaTimer->callOnTimeout(
|
||||||
this,
|
this,
|
||||||
[this]() {
|
[this]() {
|
||||||
@ -531,7 +536,7 @@ QString DeviceConnection::handleCommand(const std::string_view &replyText, const
|
|||||||
m_commandSocket->close();
|
m_commandSocket->close();
|
||||||
m_h264Socket->close();
|
m_h264Socket->close();
|
||||||
},
|
},
|
||||||
Qt::SingleShotConnection);
|
type);
|
||||||
m_otaTimer->start(60 * 1000);
|
m_otaTimer->start(60 * 1000);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -155,7 +155,11 @@ void DeviceListModel::onDeviceConnected() {
|
|||||||
std::find_if(m_devices.cbegin(), m_devices.cend(),
|
std::find_if(m_devices.cbegin(), m_devices.cend(),
|
||||||
[device](const std::shared_ptr<DeviceConnection> &item) { return item.get() == device; });
|
[device](const std::shared_ptr<DeviceConnection> &item) { return item.get() == device; });
|
||||||
if (iterator != m_devices.cend()) {
|
if (iterator != m_devices.cend()) {
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
QList<int> roles;
|
QList<int> roles;
|
||||||
|
#else
|
||||||
|
QVector<int> roles;
|
||||||
|
#endif
|
||||||
roles << OnlineStatusRole;
|
roles << OnlineStatusRole;
|
||||||
int row = std::distance(m_devices.cbegin(), iterator);
|
int row = std::distance(m_devices.cbegin(), iterator);
|
||||||
emit dataChanged(index(row), index(row), roles);
|
emit dataChanged(index(row), index(row), roles);
|
||||||
@ -170,7 +174,11 @@ void DeviceListModel::onDeviceDisconnected() {
|
|||||||
[device](const std::shared_ptr<DeviceConnection> &item) { return item.get() == device; });
|
[device](const std::shared_ptr<DeviceConnection> &item) { return item.get() == device; });
|
||||||
if (iterator != m_devices.cend()) {
|
if (iterator != m_devices.cend()) {
|
||||||
int row = std::distance(m_devices.cbegin(), iterator);
|
int row = std::distance(m_devices.cbegin(), iterator);
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
QList<int> roles;
|
QList<int> roles;
|
||||||
|
#else
|
||||||
|
QVector<int> roles;
|
||||||
|
#endif
|
||||||
roles << OnlineStatusRole;
|
roles << OnlineStatusRole;
|
||||||
emit dataChanged(index(row), index(row), roles);
|
emit dataChanged(index(row), index(row), roles);
|
||||||
LOG(info) << "device " << row << " disconnected.";
|
LOG(info) << "device " << row << " disconnected.";
|
||||||
@ -218,7 +226,11 @@ void DeviceListModel::onDeviceReplyReadyRead() {
|
|||||||
if ((m_timerId < 0) ||
|
if ((m_timerId < 0) ||
|
||||||
((info.ip == DeviceConnection::WirelessAddress) && (device.ip != DeviceConnection::WirelessAddress)) ||
|
((info.ip == DeviceConnection::WirelessAddress) && (device.ip != DeviceConnection::WirelessAddress)) ||
|
||||||
((device.ip != DeviceConnection::WirelessAddress) && (device.ip != info.ip))) {
|
((device.ip != DeviceConnection::WirelessAddress) && (device.ip != info.ip))) {
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
QList<int> roles;
|
QList<int> roles;
|
||||||
|
#else
|
||||||
|
QVector<int> roles;
|
||||||
|
#endif
|
||||||
roles << OnlineStatusRole << IpRole;
|
roles << OnlineStatusRole << IpRole;
|
||||||
int row = std::distance(m_devices.cbegin(), iterator);
|
int row = std::distance(m_devices.cbegin(), iterator);
|
||||||
emit dataChanged(index(row), index(row), roles);
|
emit dataChanged(index(row), index(row), roles);
|
||||||
|
3
main.cpp
3
main.cpp
@ -4,6 +4,7 @@
|
|||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
#include <QQuickStyle>
|
#include <QQuickStyle>
|
||||||
|
#include <QQuickWindow>
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
using namespace Amass;
|
using namespace Amass;
|
||||||
@ -14,6 +15,6 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
auto app = Singleton<Application>::instance<Construct>(argc, argv);
|
auto app = Singleton<Application>::instance<Construct>(argc, argv);
|
||||||
QQuickStyle::setStyle("Material");
|
QQuickStyle::setStyle("Material");
|
||||||
|
// QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenVG);
|
||||||
return app->exec();
|
return app->exec();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import QtQuick
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls 2.15
|
||||||
|
|
||||||
Popup {
|
Popup {
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import QtQuick
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts 1.15
|
||||||
import AntiClipSettings
|
import AntiClipSettings 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import QtQuick
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: root
|
id: root
|
||||||
|
12
qml/Main.qml
12
qml/Main.qml
@ -1,8 +1,10 @@
|
|||||||
import QtQuick
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts 1.15
|
||||||
import QtQuick.Dialogs
|
import QtQuick.Dialogs
|
||||||
import AntiClipSettings
|
import AntiClipSettings 1.0
|
||||||
|
import Qt.labs.platform 1.1 as Labs
|
||||||
|
|
||||||
|
|
||||||
ApplicationWindow {
|
ApplicationWindow {
|
||||||
id: window
|
id: window
|
||||||
@ -114,7 +116,7 @@ ApplicationWindow {
|
|||||||
id: otaPopup
|
id: otaPopup
|
||||||
}
|
}
|
||||||
|
|
||||||
FolderDialog {
|
Labs.FolderDialog {
|
||||||
id: folderDialog
|
id: folderDialog
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
App.collector.path = folderDialog.selectedFolder
|
App.collector.path = folderDialog.selectedFolder
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import QtQuick
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls 2.15
|
||||||
|
|
||||||
Dialog {
|
Dialog {
|
||||||
id: control
|
id: control
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import QtQuick
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts 1.15
|
||||||
import AntiClipSettings
|
import AntiClipSettings 1.0
|
||||||
|
|
||||||
Popup {
|
Popup {
|
||||||
id: root
|
id: root
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import QtCore
|
import QtQuick 2.15
|
||||||
import QtQuick
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Controls
|
import QtQuick.Layouts 1.15
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Dialogs
|
import QtQuick.Dialogs
|
||||||
import AntiClipSettings
|
import AntiClipSettings 1.0
|
||||||
|
|
||||||
Popup {
|
Popup {
|
||||||
id: root
|
id: root
|
||||||
@ -96,14 +95,19 @@ Popup {
|
|||||||
FileDialog {
|
FileDialog {
|
||||||
id: fileDialog
|
id: fileDialog
|
||||||
nameFilters: ["OTA文件 (*.bin)"]
|
nameFilters: ["OTA文件 (*.bin)"]
|
||||||
currentFolder: StandardPaths.standardLocations(
|
|
||||||
StandardPaths.DesktopLocation)[0]
|
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
var fileUrl = fileDialog.selectedFile.toString()
|
var fileUrl = fileDialog.selectedFile.toString()
|
||||||
var localFilePath = fileUrl.startsWith(
|
var localFilePath = fileUrl.startsWith(
|
||||||
"file:///") ? fileUrl.substring(8) : fileUrl
|
"file:///") ? fileUrl.substring(8) : fileUrl
|
||||||
otaFile.text = localFilePath
|
otaFile.text = localFilePath
|
||||||
}
|
}
|
||||||
|
onVisibleChanged: {
|
||||||
|
if(!isQt5){
|
||||||
|
currentFolder= StandardPaths.standardLocations(
|
||||||
|
StandardPaths.DesktopLocation)[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import QtQuick
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls 2.15
|
||||||
|
|
||||||
Popup{
|
Popup{
|
||||||
id: control
|
id: control
|
||||||
|
Loading…
Reference in New Issue
Block a user