mirror of
https://github.com/zhuzichu520/FluentUI.git
synced 2025-07-01 23:51:48 +08:00
Compare commits
155 Commits
Author | SHA1 | Date | |
---|---|---|---|
70e525f51e | |||
72610da66e | |||
fde55d254c | |||
61659b5e31 | |||
f4112ee5dc | |||
f973f006d2 | |||
38ea91964e | |||
af6e39d8c0 | |||
6d2a8cde7a | |||
2bd0a831e7 | |||
1bf992ed69 | |||
ecd0f29d30 | |||
5e38493403 | |||
c5aad9feed | |||
d347512486 | |||
136e2c72af | |||
95f48b51bf | |||
7ba06d183d | |||
9ee50a585a | |||
c95ac86377 | |||
5787e308dd | |||
08c458c2a1 | |||
299eba18ac | |||
6da8117056 | |||
e5668869b9 | |||
65905b139e | |||
6974b0efa6 | |||
3c924bb0de | |||
ec2378a07a | |||
863c88411b | |||
6b6dbf27a1 | |||
dc37a151c8 | |||
6c86e61916 | |||
33c203fcb3 | |||
7086df10f0 | |||
13223a11a2 | |||
3d65bdc913 | |||
c80689e376 | |||
1abbc4593a | |||
c1ffce06aa | |||
bd8a561590 | |||
eed96b4c0e | |||
1b4fddec61 | |||
2c16f6f71a | |||
3770969097 | |||
d255f5881e | |||
711411f6a8 | |||
f5a4fc1300 | |||
bc0c36772f | |||
46148b3c5c | |||
b4f2f68135 | |||
5d4cfa5286 | |||
ee23554cb4 | |||
a9772a8fb0 | |||
2428a38194 | |||
1a21cd7b31 | |||
bcc47c1496 | |||
95a6be3d28 | |||
9a48880e84 | |||
4f60459166 | |||
29749a5761 | |||
1b3344e9f9 | |||
394d0ab244 | |||
6a925bdad3 | |||
6999067a80 | |||
1047fac4d6 | |||
3b2982a95e | |||
e37d47f629 | |||
d07383ba46 | |||
ce3da2e92f | |||
2e8be5f133 | |||
8662eb97aa | |||
55a77eba4b | |||
5dd3320f66 | |||
3b4c327528 | |||
412842d844 | |||
2242ffc367 | |||
d485ec9e3b | |||
05251e085c | |||
78f5dd0a61 | |||
2f3ed2bd0f | |||
35d85aa801 | |||
542ea0a7b9 | |||
b981ecca7d | |||
a7552e2b5c | |||
637a0f312e | |||
e3e4592ea4 | |||
71c238e62b | |||
77ae88f518 | |||
2f9090858b | |||
5d11064011 | |||
dfb80e70ee | |||
7618fe0f37 | |||
cbebb51d62 | |||
f0227c5686 | |||
24c8644d79 | |||
40ce63e1df | |||
cc4abbf79f | |||
35921ed900 | |||
661529f1f4 | |||
139c5c455d | |||
3460b59839 | |||
bdbd5d295e | |||
51637fceca | |||
7f542edba7 | |||
0b124ec9ee | |||
fa77ed6163 | |||
eef46a2dac | |||
f856fd44c1 | |||
35bfb8021f | |||
29012f0b68 | |||
54b98c8e05 | |||
20852ac6bf | |||
636dddaa84 | |||
50a6103584 | |||
a693db76c8 | |||
25e385c06e | |||
777459e35d | |||
9bdc6c45cd | |||
fc618e96c5 | |||
cac1864d65 | |||
9846415838 | |||
840ae7ec2f | |||
05f51c788e | |||
19a5883e76 | |||
da0184f70e | |||
ea79becd08 | |||
1e5c70c7b4 | |||
c6a43c41db | |||
5f6d66b6ce | |||
83f94630f1 | |||
ac63514451 | |||
4d197d2697 | |||
b78aaaad48 | |||
3784a86936 | |||
0ee0c8c68f | |||
ec2ddc24eb | |||
baf5438262 | |||
b452218e79 | |||
cb5b9d8541 | |||
4ec772fff2 | |||
8f9c529153 | |||
483c5f8e09 | |||
0402b07dba | |||
ee071ee451 | |||
487cbefd82 | |||
b836b25028 | |||
0eacc177d0 | |||
9b5167d92e | |||
3a775a8bb2 | |||
0030c44a6c | |||
83cd2873c6 | |||
f385e34d23 | |||
fc1b62d4a3 | |||
9985053f82 |
@ -30,6 +30,7 @@ SolidCompression=yes
|
|||||||
WizardStyle=modern
|
WizardStyle=modern
|
||||||
UninstallDisplayIcon={app}\{#MyAppExeName}
|
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||||
SetupIconFile=.\..\favicon.ico
|
SetupIconFile=.\..\favicon.ico
|
||||||
|
MinVersion = 6.0
|
||||||
|
|
||||||
[Languages]
|
[Languages]
|
||||||
Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
|
Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
|
||||||
|
@ -58,8 +58,8 @@ if (${QMLPLUGIN_LIBTYPE} MATCHES "SHARED")
|
|||||||
set(INSTALL_QMLDIR_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR}/qmldir ${QMLPLUGIN_BINARY_DIR}/qmldir)
|
set(INSTALL_QMLDIR_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR}/qmldir ${QMLPLUGIN_BINARY_DIR}/qmldir)
|
||||||
set(COPY_QMLTYPES_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR}/plugins.qmltypes $<TARGET_FILE_DIR:${TARGET}>/${QMLPLUGIN_URI}/plugins.qmltypes)
|
set(COPY_QMLTYPES_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR}/plugins.qmltypes $<TARGET_FILE_DIR:${TARGET}>/${QMLPLUGIN_URI}/plugins.qmltypes)
|
||||||
set(INSTALL_QMLTYPES_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR}/plugins.qmltypes ${QMLPLUGIN_BINARY_DIR}/plugins.qmltypes)
|
set(INSTALL_QMLTYPES_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR}/plugins.qmltypes ${QMLPLUGIN_BINARY_DIR}/plugins.qmltypes)
|
||||||
set(COPY_LIBRARY_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_FILE_NAME:${TARGET}> $<TARGET_FILE_DIR:${TARGET}>/${QMLPLUGIN_URI})
|
set(COPY_LIBRARY_COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE_DIR:${TARGET}>/$<TARGET_FILE_NAME:${TARGET}> $<TARGET_FILE_DIR:${TARGET}>/${QMLPLUGIN_URI})
|
||||||
set(INSTALL_LIBRARY_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_FILE_NAME:${TARGET}> ${QMLPLUGIN_BINARY_DIR})
|
set(INSTALL_LIBRARY_COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE_DIR:${TARGET}>/$<TARGET_FILE_NAME:${TARGET}> ${QMLPLUGIN_BINARY_DIR})
|
||||||
if(QMLPLUGIN_QMLDIR)
|
if(QMLPLUGIN_QMLDIR)
|
||||||
set(COPY_QMLFILES_COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR} $<TARGET_FILE_DIR:${TARGET}>/${QMLPLUGIN_URI})
|
set(COPY_QMLFILES_COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR} $<TARGET_FILE_DIR:${TARGET}>/${QMLPLUGIN_URI})
|
||||||
else()
|
else()
|
||||||
|
@ -31,4 +31,4 @@ BEGIN
|
|||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
IDI_ICON1 ICON DISCARDABLE "${CMAKE_SOURCE_DIR}/example/favicon.ico"
|
IDI_ICON1 ICON DISCARDABLE "${FLUENTUI_DIRECTORY}/example/favicon.ico"
|
||||||
|
10
.github/workflows/macos.yml
vendored
10
.github/workflows/macos.yml
vendored
@ -21,8 +21,8 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-12]
|
os: [macos-13]
|
||||||
qt_ver: [6.5.0]
|
qt_ver: [6.6.0]
|
||||||
qt_arch: [clang_64]
|
qt_arch: [clang_64]
|
||||||
env:
|
env:
|
||||||
targetName: example
|
targetName: example
|
||||||
@ -50,17 +50,17 @@ jobs:
|
|||||||
cmake --version
|
cmake --version
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/FluentUI/Qt/6.5.0/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/FluentUI/Qt/6.6.0/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||||
cmake --build . --target all --config Release --parallel
|
cmake --build . --target all --config Release --parallel
|
||||||
|
|
||||||
- name: package
|
- name: package
|
||||||
run: |
|
run: |
|
||||||
# 拷贝依赖
|
# 拷贝依赖
|
||||||
macdeployqt bin/release/${targetName}.app -qmldir=. -verbose=1 -dmg
|
sudo macdeployqt bin/release/${targetName}.app -qmldir=. -dmg
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}.zip
|
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}
|
||||||
path: bin/release/${{ env.targetName }}.app
|
path: bin/release/${{ env.targetName }}.app
|
||||||
|
|
||||||
- name: uploadRelease
|
- name: uploadRelease
|
||||||
|
4
.github/workflows/ubuntu.yml
vendored
4
.github/workflows/ubuntu.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-20.04]
|
os: [ubuntu-20.04]
|
||||||
qt_ver: [6.5.0]
|
qt_ver: [6.6.0]
|
||||||
qt_arch: [gcc_64]
|
qt_arch: [gcc_64]
|
||||||
env:
|
env:
|
||||||
targetName: example
|
targetName: example
|
||||||
@ -55,7 +55,7 @@ jobs:
|
|||||||
cmake --version
|
cmake --version
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/home/runner/work/FluentUI/Qt/6.5.0/gcc_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/home/runner/work/FluentUI/Qt/6.6.0/gcc_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||||
cmake --build . --target all --config Release --parallel
|
cmake --build . --target all --config Release --parallel
|
||||||
|
|
||||||
- name: install QT linux deploy
|
- name: install QT linux deploy
|
||||||
|
4
.github/workflows/windows-mingw.yml
vendored
4
.github/workflows/windows-mingw.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
|||||||
os: [windows-2022]
|
os: [windows-2022]
|
||||||
include:
|
include:
|
||||||
- qt_arch: win64_mingw
|
- qt_arch: win64_mingw
|
||||||
qt_ver: 6.5.0
|
qt_ver: 6.6.0
|
||||||
qt_tools: "tools_mingw,9.0.0-1-202203221220,qt.tools.win64_mingw900"
|
qt_tools: "tools_mingw,9.0.0-1-202203221220,qt.tools.win64_mingw900"
|
||||||
qt_tools_mingw_install: mingw900_64
|
qt_tools_mingw_install: mingw900_64
|
||||||
env:
|
env:
|
||||||
@ -69,7 +69,7 @@ jobs:
|
|||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
ninja --version
|
ninja --version
|
||||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\FluentUI\Qt\6.5.0\mingw_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\FluentUI\Qt\6.6.0\mingw_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||||
cmake --build . --target all --config Release --parallel
|
cmake --build . --target all --config Release --parallel
|
||||||
|
|
||||||
- name: package
|
- name: package
|
||||||
|
4
.github/workflows/windows.yml
vendored
4
.github/workflows/windows.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
os: [windows-2019]
|
os: [windows-2019]
|
||||||
include:
|
include:
|
||||||
- qt_ver: 6.5.0
|
- qt_ver: 6.6.0
|
||||||
qt_arch: win64_msvc2019_64
|
qt_arch: win64_msvc2019_64
|
||||||
msvc_arch: x64
|
msvc_arch: x64
|
||||||
qt_arch_install: msvc2019_64
|
qt_arch_install: msvc2019_64
|
||||||
@ -52,7 +52,7 @@ jobs:
|
|||||||
ninja --version
|
ninja --version
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\FluentUI\Qt\6.5.0\msvc2019_64 -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\FluentUI\Qt\6.6.0\msvc2019_64 -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||||
cmake --build . --target all --config Release --parallel
|
cmake --build . --target all --config Release --parallel
|
||||||
echo winSdkDir=%WindowsSdkDir% >> %GITHUB_ENV%
|
echo winSdkDir=%WindowsSdkDir% >> %GITHUB_ENV%
|
||||||
echo winSdkVer=%WindowsSdkVersion% >> %GITHUB_ENV%
|
echo winSdkVer=%WindowsSdkVersion% >> %GITHUB_ENV%
|
||||||
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -1,6 +0,0 @@
|
|||||||
[submodule "framelesshelper"]
|
|
||||||
path = framelesshelper
|
|
||||||
url = https://github.com/zhuzichu520/framelesshelper.git
|
|
||||||
[submodule "zxing-cpp"]
|
|
||||||
path = zxing-cpp
|
|
||||||
url = https://github.com/zhuzichu520/zxing-cpp.git
|
|
@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
|
||||||
project(FluentUI VERSION 0.1 LANGUAGES CXX)
|
project(FluentUI VERSION 1.0)
|
||||||
|
|
||||||
set(FLUENTUI_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
set(FLUENTUI_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||||
list(APPEND CMAKE_MODULE_PATH ${FLUENTUI_DIRECTORY}/.cmake/)
|
list(APPEND CMAKE_MODULE_PATH ${FLUENTUI_DIRECTORY}/.cmake/)
|
||||||
@ -25,17 +25,16 @@ if(NOT FLUENTUI_QML_PLUGIN_DIRECTORY)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(zxing-cpp)
|
|
||||||
|
target_compile_definitions(fluentuiplugin
|
||||||
|
PRIVATE
|
||||||
|
QT_MESSAGELOGCONTEXT
|
||||||
|
)
|
||||||
|
|
||||||
if (FLUENTUI_BUILD_EXAMPLES)
|
if (FLUENTUI_BUILD_EXAMPLES)
|
||||||
add_subdirectory(example)
|
add_subdirectory(example)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(FRAMELESSHELPER_BUILD_STATIC ON)
|
|
||||||
set(FRAMELESSHELPER_NO_DEBUG_OUTPUT ON)
|
|
||||||
set(FRAMELESSHELPER_BUILD_WIDGETS OFF)
|
|
||||||
add_subdirectory(framelesshelper)
|
|
||||||
|
|
||||||
message("------------------------ FluentUI ------------------------")
|
message("------------------------ FluentUI ------------------------")
|
||||||
message("Build FluentUI demo applications.: ${FLUENTUI_BUILD_EXAMPLES}")
|
message("Build FluentUI demo applications.: ${FLUENTUI_BUILD_EXAMPLES}")
|
||||||
message("Build static library.: ${FLUENTUI_BUILD_STATIC_LIB}")
|
message("Build static library.: ${FLUENTUI_BUILD_STATIC_LIB}")
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
|
||||||
project(example VERSION 0.1 LANGUAGES CXX)
|
project(example VERSION 1.0)
|
||||||
|
|
||||||
#配置通用编译
|
#配置通用编译
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
if(APPLE)
|
|
||||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#导入exmaple的QML位置,不然import example有时候会爆红
|
#导入exmaple的QML位置,不然import example有时候会爆红
|
||||||
set(QML_IMPORT_PATH ${CMAKE_BINARY_DIR}/example CACHE STRING "Qt Creator extra QML import paths" FORCE)
|
set(QML_IMPORT_PATH ${CMAKE_BINARY_DIR}/example CACHE STRING "Qt Creator extra QML import paths" FORCE)
|
||||||
@ -18,9 +16,9 @@ endif()
|
|||||||
|
|
||||||
#设置可执行文件输出目录
|
#设置可执行文件输出目录
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/debug)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${FLUENTUI_DIRECTORY}/bin/debug>)
|
||||||
else()
|
else()
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/release)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${FLUENTUI_DIRECTORY}/bin/release>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#获取文件路径分隔符(解决执行命令的时候有些平台会报错)
|
#获取文件路径分隔符(解决执行命令的时候有些平台会报错)
|
||||||
@ -79,10 +77,10 @@ if(WIN32)
|
|||||||
${FLUENTUI_DIRECTORY}/.cmake/version_exe.rc.in
|
${FLUENTUI_DIRECTORY}/.cmake/version_exe.rc.in
|
||||||
${EXAMPLE_VERSION_RC_PATH}
|
${EXAMPLE_VERSION_RC_PATH}
|
||||||
)
|
)
|
||||||
configure_file(
|
configure_file(
|
||||||
${FLUENTUI_DIRECTORY}/.cmake/InstallerScript.iss.in
|
${FLUENTUI_DIRECTORY}/.cmake/InstallerScript.iss.in
|
||||||
${CMAKE_SOURCE_DIR}/action-cli/InstallerScript.iss
|
${FLUENTUI_DIRECTORY}/action-cli/InstallerScript.iss
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#添加可执行文件
|
#添加可执行文件
|
||||||
@ -139,7 +137,7 @@ target_include_directories(example PRIVATE
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/component
|
${CMAKE_CURRENT_SOURCE_DIR}/src/component
|
||||||
)
|
)
|
||||||
|
|
||||||
#如何是静态库则需要手动注册插件,导入FluentUI.h头文件
|
#如果是静态库则需要手动注册插件,导入FluentUI.h头文件
|
||||||
if(FLUENTUI_BUILD_STATIC_LIB)
|
if(FLUENTUI_BUILD_STATIC_LIB)
|
||||||
target_include_directories(example PRIVATE
|
target_include_directories(example PRIVATE
|
||||||
${CMAKE_SOURCE_DIR}/src
|
${CMAKE_SOURCE_DIR}/src
|
||||||
@ -155,6 +153,11 @@ set_target_properties(example PROPERTIES
|
|||||||
WIN32_EXECUTABLE TRUE
|
WIN32_EXECUTABLE TRUE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(example
|
||||||
|
PRIVATE
|
||||||
|
QT_MESSAGELOGCONTEXT
|
||||||
|
)
|
||||||
|
|
||||||
target_link_libraries(example PRIVATE
|
target_link_libraries(example PRIVATE
|
||||||
Qt${QT_VERSION_MAJOR}::Quick
|
Qt${QT_VERSION_MAJOR}::Quick
|
||||||
Qt${QT_VERSION_MAJOR}::Svg
|
Qt${QT_VERSION_MAJOR}::Svg
|
||||||
|
@ -134,7 +134,6 @@
|
|||||||
<file>qml/page/T_CalendarPicker.qml</file>
|
<file>qml/page/T_CalendarPicker.qml</file>
|
||||||
<file>qml/page/T_Captcha.qml</file>
|
<file>qml/page/T_Captcha.qml</file>
|
||||||
<file>qml/page/T_Carousel.qml</file>
|
<file>qml/page/T_Carousel.qml</file>
|
||||||
<file>qml/page/T_Chart.qml</file>
|
|
||||||
<file>qml/page/T_CheckBox.qml</file>
|
<file>qml/page/T_CheckBox.qml</file>
|
||||||
<file>qml/page/T_ColorPicker.qml</file>
|
<file>qml/page/T_ColorPicker.qml</file>
|
||||||
<file>qml/page/T_ComboBox.qml</file>
|
<file>qml/page/T_ComboBox.qml</file>
|
||||||
@ -143,7 +142,6 @@
|
|||||||
<file>qml/page/T_Expander.qml</file>
|
<file>qml/page/T_Expander.qml</file>
|
||||||
<file>qml/page/T_FlipView.qml</file>
|
<file>qml/page/T_FlipView.qml</file>
|
||||||
<file>qml/page/T_Home.qml</file>
|
<file>qml/page/T_Home.qml</file>
|
||||||
<file>qml/page/T_Http.qml</file>
|
|
||||||
<file>qml/page/T_Image.qml</file>
|
<file>qml/page/T_Image.qml</file>
|
||||||
<file>qml/page/T_InfoBar.qml</file>
|
<file>qml/page/T_InfoBar.qml</file>
|
||||||
<file>qml/page/T_Menu.qml</file>
|
<file>qml/page/T_Menu.qml</file>
|
||||||
@ -189,5 +187,14 @@
|
|||||||
<file>qml/page/T_Clip.qml</file>
|
<file>qml/page/T_Clip.qml</file>
|
||||||
<file>qml/page/T_3D.qml</file>
|
<file>qml/page/T_3D.qml</file>
|
||||||
<file>qml/global/Lang.qml</file>
|
<file>qml/global/Lang.qml</file>
|
||||||
|
<file>qml/page/T_Network.qml</file>
|
||||||
|
<file>qml/page/T_ShortcutPicker.qml</file>
|
||||||
|
<file>qml/chart/T_BarChart.qml</file>
|
||||||
|
<file>qml/chart/T_LineChart.qml</file>
|
||||||
|
<file>qml/chart/T_PieChart.qml</file>
|
||||||
|
<file>qml/chart/T_RadarChart.qml</file>
|
||||||
|
<file>qml/chart/T_ScatterChart.qml</file>
|
||||||
|
<file>qml/chart/T_BubbleChart.qml</file>
|
||||||
|
<file>qml/chart/T_PolarAreaChart.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -4,9 +4,8 @@ import QtQuick.Controls
|
|||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import FluentUI
|
import FluentUI
|
||||||
|
|
||||||
Window {
|
Item {
|
||||||
id: app
|
id: app
|
||||||
flags: Qt.SplashScreen
|
|
||||||
|
|
||||||
Connections{
|
Connections{
|
||||||
target: FluTheme
|
target: FluTheme
|
||||||
@ -17,30 +16,19 @@ Window {
|
|||||||
|
|
||||||
Connections{
|
Connections{
|
||||||
target: FluApp
|
target: FluApp
|
||||||
function onVsyncChanged(){
|
function onUseSystemAppBarChanged(){
|
||||||
SettingsHelper.saveVsync(FluApp.vsync)
|
SettingsHelper.saveUseSystemAppBar(FluApp.useSystemAppBar)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluHttpInterceptor{
|
|
||||||
id:interceptor
|
|
||||||
function onIntercept(request){
|
|
||||||
if(request.method === "get"){
|
|
||||||
request.params["method"] = "get"
|
|
||||||
}
|
|
||||||
if(request.method === "post"){
|
|
||||||
request.params["method"] = "post"
|
|
||||||
}
|
|
||||||
request.headers["token"] ="yyds"
|
|
||||||
request.headers["os"] ="pc"
|
|
||||||
console.debug(JSON.stringify(request))
|
|
||||||
return request
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
FluNetwork.openLog = false
|
||||||
|
FluNetwork.setInterceptor(function(param){
|
||||||
|
param.addHeader("Token","000000000000000000000")
|
||||||
|
})
|
||||||
FluApp.init(app)
|
FluApp.init(app)
|
||||||
FluApp.vsync = SettingsHelper.getVsync()
|
FluApp.windowIcon = "qrc:/example/res/image/favicon.ico"
|
||||||
|
FluApp.useSystemAppBar = SettingsHelper.getUseSystemAppBar()
|
||||||
FluTheme.darkMode = SettingsHelper.getDarkMode()
|
FluTheme.darkMode = SettingsHelper.getDarkMode()
|
||||||
FluTheme.enableAnimation = true
|
FluTheme.enableAnimation = true
|
||||||
FluApp.routes = {
|
FluApp.routes = {
|
||||||
@ -54,7 +42,6 @@ Window {
|
|||||||
"/pageWindow":"qrc:/example/qml/window/PageWindow.qml"
|
"/pageWindow":"qrc:/example/qml/window/PageWindow.qml"
|
||||||
}
|
}
|
||||||
FluApp.initialRoute = "/"
|
FluApp.initialRoute = "/"
|
||||||
FluApp.httpInterceptor = interceptor
|
|
||||||
FluApp.run()
|
FluApp.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
132
example/qml-Qt6/chart/T_BarChart.qml
Normal file
132
example/qml-Qt6/chart/T_BarChart.qml
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
import FluentUI
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Bar Chart"
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'bar'
|
||||||
|
chartData: { return {
|
||||||
|
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [65, 59, 80, 81, 56, 55, 40],
|
||||||
|
backgroundColor: [
|
||||||
|
'rgba(255, 99, 132, 0.2)',
|
||||||
|
'rgba(255, 159, 64, 0.2)',
|
||||||
|
'rgba(255, 205, 86, 0.2)',
|
||||||
|
'rgba(75, 192, 192, 0.2)',
|
||||||
|
'rgba(54, 162, 235, 0.2)',
|
||||||
|
'rgba(153, 102, 255, 0.2)',
|
||||||
|
'rgba(201, 203, 207, 0.2)'
|
||||||
|
],
|
||||||
|
borderColor: [
|
||||||
|
'rgb(255, 99, 132)',
|
||||||
|
'rgb(255, 159, 64)',
|
||||||
|
'rgb(255, 205, 86)',
|
||||||
|
'rgb(75, 192, 192)',
|
||||||
|
'rgb(54, 162, 235)',
|
||||||
|
'rgb(153, 102, 255)',
|
||||||
|
'rgb(201, 203, 207)'
|
||||||
|
],
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Bar Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
},
|
||||||
|
responsive: true,
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
stacked: true,
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
stacked: true
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'horizontalBar'
|
||||||
|
chartData: { return {
|
||||||
|
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [65, 59, 80, 81, 56, 55, 40],
|
||||||
|
backgroundColor: [
|
||||||
|
'rgba(255, 99, 132, 0.2)',
|
||||||
|
'rgba(255, 159, 64, 0.2)',
|
||||||
|
'rgba(255, 205, 86, 0.2)',
|
||||||
|
'rgba(75, 192, 192, 0.2)',
|
||||||
|
'rgba(54, 162, 235, 0.2)',
|
||||||
|
'rgba(153, 102, 255, 0.2)',
|
||||||
|
'rgba(201, 203, 207, 0.2)'
|
||||||
|
],
|
||||||
|
borderColor: [
|
||||||
|
'rgb(255, 99, 132)',
|
||||||
|
'rgb(255, 159, 64)',
|
||||||
|
'rgb(255, 205, 86)',
|
||||||
|
'rgb(75, 192, 192)',
|
||||||
|
'rgb(54, 162, 235)',
|
||||||
|
'rgb(153, 102, 255)',
|
||||||
|
'rgb(201, 203, 207)'
|
||||||
|
],
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js HorizontalBar Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
},
|
||||||
|
responsive: true,
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
stacked: true,
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
stacked: true
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
74
example/qml-Qt6/chart/T_BubbleChart.qml
Normal file
74
example/qml-Qt6/chart/T_BubbleChart.qml
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
import FluentUI
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Bubble Chart"
|
||||||
|
|
||||||
|
function randomScalingFactor() {
|
||||||
|
return Math.random().toFixed(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
height: 370
|
||||||
|
width: 500
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'bubble'
|
||||||
|
chartData: {
|
||||||
|
return {
|
||||||
|
datasets: [{
|
||||||
|
label: 'First Dataset',
|
||||||
|
data: [{
|
||||||
|
x: 20,
|
||||||
|
y: 30,
|
||||||
|
r: 15
|
||||||
|
}, {
|
||||||
|
x: 12,
|
||||||
|
y: 70,
|
||||||
|
r: 20
|
||||||
|
}, {
|
||||||
|
x: 11,
|
||||||
|
y: 28,
|
||||||
|
r: 8
|
||||||
|
}, {
|
||||||
|
x: 9,
|
||||||
|
y: 28,
|
||||||
|
r: 10
|
||||||
|
}, {
|
||||||
|
x: 43,
|
||||||
|
y: 7,
|
||||||
|
r: 14
|
||||||
|
}, {
|
||||||
|
x: 22,
|
||||||
|
y: 22,
|
||||||
|
r: 12
|
||||||
|
}, {
|
||||||
|
x: 40,
|
||||||
|
y: 10,
|
||||||
|
r: 10
|
||||||
|
}],
|
||||||
|
backgroundColor: 'rgb(255, 99, 132)'
|
||||||
|
}]
|
||||||
|
}}
|
||||||
|
chartOptions: {return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
responsive: true,
|
||||||
|
hoverMode: 'nearest',
|
||||||
|
intersect: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Bubble Chart - Multi Axis'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
45
example/qml-Qt6/chart/T_LineChart.qml
Normal file
45
example/qml-Qt6/chart/T_LineChart.qml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
import FluentUI
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Line Chart"
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'line'
|
||||||
|
chartData: { return {
|
||||||
|
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [65, 59, 80, 81, 56, 55, 40],
|
||||||
|
fill: false,
|
||||||
|
borderColor: 'rgb(75, 192, 192)',
|
||||||
|
tension: 0.1
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Line Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
93
example/qml-Qt6/chart/T_PieChart.qml
Normal file
93
example/qml-Qt6/chart/T_PieChart.qml
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
import FluentUI
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Doughnut and Pie Chart"
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: "doughnut"
|
||||||
|
chartData: { return {
|
||||||
|
labels: [
|
||||||
|
'Red',
|
||||||
|
'Blue',
|
||||||
|
'Yellow'
|
||||||
|
],
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [300, 50, 100],
|
||||||
|
backgroundColor: [
|
||||||
|
'rgb(255, 99, 132)',
|
||||||
|
'rgb(54, 162, 235)',
|
||||||
|
'rgb(255, 205, 86)'
|
||||||
|
],
|
||||||
|
hoverOffset: 4
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Doughnut Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: "pie"
|
||||||
|
chartData: { return {
|
||||||
|
labels: [
|
||||||
|
'Red',
|
||||||
|
'Blue',
|
||||||
|
'Yellow'
|
||||||
|
],
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [300, 50, 100],
|
||||||
|
backgroundColor: [
|
||||||
|
'rgb(255, 99, 132)',
|
||||||
|
'rgb(54, 162, 235)',
|
||||||
|
'rgb(255, 205, 86)'
|
||||||
|
],
|
||||||
|
hoverOffset: 4
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Pie Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
example/qml-Qt6/chart/T_PolarAreaChart.qml
Normal file
57
example/qml-Qt6/chart/T_PolarAreaChart.qml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
import FluentUI
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"PolarArea Chart"
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'polarArea'
|
||||||
|
chartData: { return {
|
||||||
|
labels: [
|
||||||
|
'Red',
|
||||||
|
'Green',
|
||||||
|
'Yellow',
|
||||||
|
'Grey',
|
||||||
|
'Blue'
|
||||||
|
],
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [11, 16, 7, 3, 14],
|
||||||
|
backgroundColor: [
|
||||||
|
'rgb(255, 99, 132)',
|
||||||
|
'rgb(75, 192, 192)',
|
||||||
|
'rgb(255, 205, 86)',
|
||||||
|
'rgb(201, 203, 207)',
|
||||||
|
'rgb(54, 162, 235)'
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js PolarArea Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
74
example/qml-Qt6/chart/T_RadarChart.qml
Normal file
74
example/qml-Qt6/chart/T_RadarChart.qml
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
import FluentUI
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Radar Chart"
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'radar'
|
||||||
|
chartData: { return {
|
||||||
|
labels: [
|
||||||
|
'Eating',
|
||||||
|
'Drinking',
|
||||||
|
'Sleeping',
|
||||||
|
'Designing',
|
||||||
|
'Coding',
|
||||||
|
'Cycling',
|
||||||
|
'Running'
|
||||||
|
],
|
||||||
|
datasets:
|
||||||
|
[{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [65, 59, 90, 81, 56, 55, 40],
|
||||||
|
fill: true,
|
||||||
|
backgroundColor: 'rgba(255, 99, 132, 0.2)',
|
||||||
|
borderColor: 'rgb(255, 99, 132)',
|
||||||
|
pointBackgroundColor: 'rgb(255, 99, 132)',
|
||||||
|
pointBorderColor: '#fff',
|
||||||
|
pointHoverBackgroundColor: '#fff',
|
||||||
|
pointHoverBorderColor: 'rgb(255, 99, 132)'
|
||||||
|
}, {
|
||||||
|
label: 'My Second Dataset',
|
||||||
|
data: [28, 48, 40, 19, 96, 27, 100],
|
||||||
|
fill: true,
|
||||||
|
backgroundColor: 'rgba(54, 162, 235, 0.2)',
|
||||||
|
borderColor: 'rgb(54, 162, 235)',
|
||||||
|
pointBackgroundColor: 'rgb(54, 162, 235)',
|
||||||
|
pointBorderColor: '#fff',
|
||||||
|
pointHoverBackgroundColor: '#fff',
|
||||||
|
pointHoverBorderColor: 'rgb(54, 162, 235)'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Radar Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
},
|
||||||
|
elements: {
|
||||||
|
line: {
|
||||||
|
borderWidth: 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
123
example/qml-Qt6/chart/T_ScatterChart.qml
Normal file
123
example/qml-Qt6/chart/T_ScatterChart.qml
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
import FluentUI
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Scatter Chart"
|
||||||
|
|
||||||
|
function randomScalingFactor() {
|
||||||
|
return Math.random().toFixed(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
height: 370
|
||||||
|
width: 500
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'scatter'
|
||||||
|
chartData: {
|
||||||
|
return {
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First dataset',
|
||||||
|
xAxisID: 'x-axis-1',
|
||||||
|
yAxisID: 'y-axis-1',
|
||||||
|
borderColor: '#ff5555',
|
||||||
|
backgroundColor: 'rgba(255,192,192,0.3)',
|
||||||
|
data: [{
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
label: 'My Second dataset',
|
||||||
|
xAxisID: 'x-axis-1',
|
||||||
|
yAxisID: 'y-axis-2',
|
||||||
|
borderColor: '#5555ff',
|
||||||
|
backgroundColor: 'rgba(192,192,255,0.3)',
|
||||||
|
data: [{
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}}
|
||||||
|
chartOptions: {return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
responsive: true,
|
||||||
|
hoverMode: 'nearest',
|
||||||
|
intersect: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Scatter Chart - Multi Axis'
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
position: 'bottom',
|
||||||
|
gridLines: {
|
||||||
|
zeroLineColor: 'rgba(0,0,0,1)'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
|
||||||
|
display: true,
|
||||||
|
position: 'left',
|
||||||
|
id: 'y-axis-1',
|
||||||
|
}, {
|
||||||
|
type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
|
||||||
|
display: true,
|
||||||
|
position: 'right',
|
||||||
|
reverse: true,
|
||||||
|
id: 'y-axis-2',
|
||||||
|
|
||||||
|
// grid line settings
|
||||||
|
gridLines: {
|
||||||
|
drawOnChartArea: false, // only want the grid lines for one axis to show up
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -130,7 +130,6 @@ FluExpander{
|
|||||||
"FluRadioButtons",
|
"FluRadioButtons",
|
||||||
"FluImage",
|
"FluImage",
|
||||||
"FluSpinBox",
|
"FluSpinBox",
|
||||||
"FluHttp",
|
|
||||||
"FluWatermark",
|
"FluWatermark",
|
||||||
"FluTour",
|
"FluTour",
|
||||||
"FluQRCode",
|
"FluQRCode",
|
||||||
@ -140,7 +139,9 @@ FluExpander{
|
|||||||
"FluStaggeredView",
|
"FluStaggeredView",
|
||||||
"FluProgressButton",
|
"FluProgressButton",
|
||||||
"FluLoadingButton",
|
"FluLoadingButton",
|
||||||
"FluClip"
|
"FluClip",
|
||||||
|
"FluNetwork",
|
||||||
|
"FluShortcutPicker"
|
||||||
];
|
];
|
||||||
code = code.replace(/\n/g, "<br>");
|
code = code.replace(/\n/g, "<br>");
|
||||||
code = code.replace(/ /g, " ");
|
code = code.replace(/ /g, " ");
|
||||||
|
@ -6,6 +6,7 @@ import FluentUI
|
|||||||
FluObject{
|
FluObject{
|
||||||
|
|
||||||
property var navigationView
|
property var navigationView
|
||||||
|
property var paneItemMenu
|
||||||
|
|
||||||
id:footer_items
|
id:footer_items
|
||||||
|
|
||||||
@ -14,7 +15,6 @@ FluObject{
|
|||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:Lang.about
|
title:Lang.about
|
||||||
icon:FluentIcons.Contact
|
icon:FluentIcons.Contact
|
||||||
onDropped: { FluApp.navigate("/about") }
|
|
||||||
onTapListener:function(){
|
onTapListener:function(){
|
||||||
FluApp.navigate("/about")
|
FluApp.navigate("/about")
|
||||||
}
|
}
|
||||||
@ -22,9 +22,9 @@ FluObject{
|
|||||||
|
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:Lang.settings
|
title:Lang.settings
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
icon:FluentIcons.Settings
|
icon:FluentIcons.Settings
|
||||||
url:"qrc:/example/qml/page/T_Settings.qml"
|
url:"qrc:/example/qml/page/T_Settings.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{
|
onTap:{
|
||||||
navigationView.push(url)
|
navigationView.push(url)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import FluentUI
|
|||||||
FluObject{
|
FluObject{
|
||||||
|
|
||||||
property var navigationView
|
property var navigationView
|
||||||
|
property var paneItemMenu
|
||||||
|
|
||||||
function rename(item, newName){
|
function rename(item, newName){
|
||||||
if(newName && newName.trim().length>0){
|
if(newName && newName.trim().length>0){
|
||||||
@ -17,32 +18,18 @@ FluObject{
|
|||||||
id:item_home
|
id:item_home
|
||||||
count: 9
|
count: 9
|
||||||
title:Lang.home
|
title:Lang.home
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
infoBadge:FluBadge{
|
infoBadge:FluBadge{
|
||||||
count: item_home.count
|
count: item_home.count
|
||||||
}
|
}
|
||||||
icon:FluentIcons.Home
|
icon:FluentIcons.Home
|
||||||
url:"qrc:/example/qml/page/T_Home.qml"
|
url:"qrc:/example/qml/page/T_Home.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{
|
onTap:{
|
||||||
if(navigationView.getCurrentUrl()){
|
if(navigationView.getCurrentUrl()){
|
||||||
item_home.count = 0
|
item_home.count = 0
|
||||||
}
|
}
|
||||||
navigationView.push(url)
|
navigationView.push(url)
|
||||||
}
|
}
|
||||||
editDelegate: FluTextBox{
|
|
||||||
text:item_home.title
|
|
||||||
}
|
|
||||||
menuDelegate: FluMenu{
|
|
||||||
id:nav_item_right_menu
|
|
||||||
width: 120
|
|
||||||
FluMenuItem{
|
|
||||||
text: "重命名"
|
|
||||||
visible: true
|
|
||||||
onClicked: {
|
|
||||||
item_home.showEdit = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FluPaneItemExpander{
|
FluPaneItemExpander{
|
||||||
@ -55,18 +42,6 @@ FluObject{
|
|||||||
id:item_expander_basic_input
|
id:item_expander_basic_input
|
||||||
title:Lang.basic_input
|
title:Lang.basic_input
|
||||||
icon:FluentIcons.CheckboxComposite
|
icon:FluentIcons.CheckboxComposite
|
||||||
editDelegate: FluTextBox{
|
|
||||||
text:item_expander_basic_input.title
|
|
||||||
}
|
|
||||||
menuDelegate: FluMenu{
|
|
||||||
FluMenuItem{
|
|
||||||
text: "重命名"
|
|
||||||
visible: true
|
|
||||||
onClicked: {
|
|
||||||
item_expander_basic_input.showEdit = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
id:item_buttons
|
id:item_buttons
|
||||||
count: 99
|
count: 99
|
||||||
@ -74,11 +49,11 @@ FluObject{
|
|||||||
count: item_buttons.count
|
count: item_buttons.count
|
||||||
}
|
}
|
||||||
title:"Buttons"
|
title:"Buttons"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/Button.png"
|
image:"qrc:/example/res/image/control/Button.png"
|
||||||
recentlyUpdated:true
|
recentlyUpdated:true
|
||||||
desc:"A control that responds to user input and raisesa Click event."
|
desc:"A control that responds to user input and raisesa Click event."
|
||||||
url:"qrc:/example/qml/page/T_Buttons.qml"
|
url:"qrc:/example/qml/page/T_Buttons.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{
|
onTap:{
|
||||||
item_buttons.count = 0
|
item_buttons.count = 0
|
||||||
navigationView.push(url)
|
navigationView.push(url)
|
||||||
@ -87,13 +62,13 @@ FluObject{
|
|||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
id:item_text
|
id:item_text
|
||||||
title:"Text"
|
title:"Text"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
count: 5
|
count: 5
|
||||||
infoBadge:FluBadge{
|
infoBadge:FluBadge{
|
||||||
count: item_text.count
|
count: item_text.count
|
||||||
color: Qt.rgba(82/255,196/255,26/255,1)
|
color: Qt.rgba(82/255,196/255,26/255,1)
|
||||||
}
|
}
|
||||||
url:"qrc:/example/qml/page/T_Text.qml"
|
url:"qrc:/example/qml/page/T_Text.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{
|
onTap:{
|
||||||
item_text.count = 0
|
item_text.count = 0
|
||||||
navigationView.push(url)
|
navigationView.push(url)
|
||||||
@ -101,38 +76,38 @@ FluObject{
|
|||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Image"
|
title:"Image"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Image.qml"
|
url:"qrc:/example/qml/page/T_Image.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Slider"
|
title:"Slider"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/Slider.png"
|
image:"qrc:/example/res/image/control/Slider.png"
|
||||||
recentlyUpdated:true
|
recentlyUpdated:true
|
||||||
desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack."
|
desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack."
|
||||||
url:"qrc:/example/qml/page/T_Slider.qml"
|
url:"qrc:/example/qml/page/T_Slider.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"CheckBox"
|
title:"CheckBox"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/Checkbox.png"
|
image:"qrc:/example/res/image/control/Checkbox.png"
|
||||||
recentlyUpdated:true
|
recentlyUpdated:true
|
||||||
desc:"A control that a user can select or clear."
|
desc:"A control that a user can select or clear."
|
||||||
url:"qrc:/example/qml/page/T_CheckBox.qml"
|
url:"qrc:/example/qml/page/T_CheckBox.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"RadioButton"
|
title:"RadioButton"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_RadioButton.qml"
|
url:"qrc:/example/qml/page/T_RadioButton.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"ToggleSwitch"
|
title:"ToggleSwitch"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_ToggleSwitch.qml"
|
url:"qrc:/example/qml/page/T_ToggleSwitch.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
@ -147,32 +122,38 @@ FluObject{
|
|||||||
icon:FluentIcons.GridView
|
icon:FluentIcons.GridView
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"TextBox"
|
title:"TextBox"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_TextBox.qml"
|
url:"qrc:/example/qml/page/T_TextBox.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"TimePicker"
|
title:"TimePicker"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_TimePicker.qml"
|
url:"qrc:/example/qml/page/T_TimePicker.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"DatePicker"
|
title:"DatePicker"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_DatePicker.qml"
|
url:"qrc:/example/qml/page/T_DatePicker.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"CalendarPicker"
|
title:"CalendarPicker"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_CalendarPicker.qml"
|
url:"qrc:/example/qml/page/T_CalendarPicker.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"ColorPicker"
|
title:"ColorPicker"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_ColorPicker.qml"
|
url:"qrc:/example/qml/page/T_ColorPicker.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:"ShortcutPicker"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/page/T_ShortcutPicker.qml"
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,71 +163,71 @@ FluObject{
|
|||||||
icon:FluentIcons.SurfaceHub
|
icon:FluentIcons.SurfaceHub
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"InfoBar"
|
title:"InfoBar"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/InfoBar.png"
|
image:"qrc:/example/res/image/control/InfoBar.png"
|
||||||
recentlyUpdated:true
|
recentlyUpdated:true
|
||||||
desc:"An inline message to display app-wide statuschange information."
|
desc:"An inline message to display app-wide statuschange information."
|
||||||
url:"qrc:/example/qml/page/T_InfoBar.qml"
|
url:"qrc:/example/qml/page/T_InfoBar.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Progress"
|
title:"Progress"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Progress.qml"
|
url:"qrc:/example/qml/page/T_Progress.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"RatingControl"
|
title:"RatingControl"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_RatingControl.qml"
|
url:"qrc:/example/qml/page/T_RatingControl.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Badge"
|
title:"Badge"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Badge.qml"
|
url:"qrc:/example/qml/page/T_Badge.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Rectangle"
|
title:"Rectangle"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Rectangle.qml"
|
url:"qrc:/example/qml/page/T_Rectangle.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Clip"
|
title:"Clip"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Clip.qml"
|
url:"qrc:/example/qml/page/T_Clip.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"StatusView"
|
title:"StatusView"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_StatusView.qml"
|
url:"qrc:/example/qml/page/T_StatusView.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Carousel"
|
title:"Carousel"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Carousel.qml"
|
url:"qrc:/example/qml/page/T_Carousel.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Expander"
|
title:"Expander"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Expander.qml"
|
url:"qrc:/example/qml/page/T_Expander.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"StaggeredView"
|
title:"StaggeredView"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_StaggeredView.qml"
|
url:"qrc:/example/qml/page/T_StaggeredView.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Watermark"
|
title:"Watermark"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Watermark.qml"
|
url:"qrc:/example/qml/page/T_Watermark.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,20 +237,20 @@ FluObject{
|
|||||||
icon:FluentIcons.ButtonMenu
|
icon:FluentIcons.ButtonMenu
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Dialog"
|
title:"Dialog"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Dialog.qml"
|
url:"qrc:/example/qml/page/T_Dialog.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
id:item_combobox
|
id:item_combobox
|
||||||
title:"ComboBox"
|
title:"ComboBox"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
count: 9
|
count: 9
|
||||||
infoBadge:FluBadge{
|
infoBadge:FluBadge{
|
||||||
count: item_combobox.count
|
count: item_combobox.count
|
||||||
color: Qt.rgba(250/255,173/255,20/255,1)
|
color: Qt.rgba(250/255,173/255,20/255,1)
|
||||||
}
|
}
|
||||||
url:"qrc:/example/qml/page/T_ComboBox.qml"
|
url:"qrc:/example/qml/page/T_ComboBox.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{
|
onTap:{
|
||||||
item_combobox.count = 0
|
item_combobox.count = 0
|
||||||
navigationView.push("qrc:/example/qml/page/T_ComboBox.qml")
|
navigationView.push("qrc:/example/qml/page/T_ComboBox.qml")
|
||||||
@ -277,14 +258,14 @@ FluObject{
|
|||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Tooltip"
|
title:"Tooltip"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Tooltip.qml"
|
url:"qrc:/example/qml/page/T_Tooltip.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Menu"
|
title:"Menu"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Menu.qml"
|
url:"qrc:/example/qml/page/T_Menu.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,66 +275,66 @@ FluObject{
|
|||||||
icon:FluentIcons.AllApps
|
icon:FluentIcons.AllApps
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Pivot"
|
title:"Pivot"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/Pivot.png"
|
image:"qrc:/example/res/image/control/Pivot.png"
|
||||||
recentlyAdded:true
|
recentlyAdded:true
|
||||||
order:3
|
order:3
|
||||||
desc:"Presents information from different sources in atabbed view."
|
desc:"Presents information from different sources in atabbed view."
|
||||||
url:"qrc:/example/qml/page/T_Pivot.qml"
|
url:"qrc:/example/qml/page/T_Pivot.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"BreadcrumbBar"
|
title:"BreadcrumbBar"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_BreadcrumbBar.qml"
|
url:"qrc:/example/qml/page/T_BreadcrumbBar.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"TabView"
|
title:"TabView"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/TabView.png"
|
image:"qrc:/example/res/image/control/TabView.png"
|
||||||
recentlyAdded:true
|
recentlyAdded:true
|
||||||
order:1
|
order:1
|
||||||
desc:"A control that displays a collection of tabs thatcan be used to display several documents."
|
desc:"A control that displays a collection of tabs thatcan be used to display several documents."
|
||||||
url:"qrc:/example/qml/page/T_TabView.qml"
|
url:"qrc:/example/qml/page/T_TabView.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"TreeView"
|
title:"TreeView"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_TreeView.qml"
|
url:"qrc:/example/qml/page/T_TreeView.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"TableView"
|
title:"TableView"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/DataGrid.png"
|
image:"qrc:/example/res/image/control/DataGrid.png"
|
||||||
recentlyAdded:true
|
recentlyAdded:true
|
||||||
order:4
|
order:4
|
||||||
desc:"The TableView control provides a flexible way to display a collection of data in rows and columns"
|
desc:"The TableView control provides a flexible way to display a collection of data in rows and columns"
|
||||||
url:"qrc:/example/qml/page/T_TableView.qml"
|
url:"qrc:/example/qml/page/T_TableView.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Pagination"
|
title:"Pagination"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Pagination.qml"
|
url:"qrc:/example/qml/page/T_Pagination.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"MultiWindow"
|
title:"MultiWindow"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_MultiWindow.qml"
|
url:"qrc:/example/qml/page/T_MultiWindow.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"FlipView"
|
title:"FlipView"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/FlipView.png"
|
image:"qrc:/example/res/image/control/FlipView.png"
|
||||||
recentlyAdded:true
|
recentlyAdded:true
|
||||||
order:2
|
order:2
|
||||||
desc:"Presents a collection of items that the user canflip through, one item at a time."
|
desc:"Presents a collection of items that the user canflip through, one item at a time."
|
||||||
url:"qrc:/example/qml/page/T_FlipView.qml"
|
url:"qrc:/example/qml/page/T_FlipView.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,26 +344,73 @@ FluObject{
|
|||||||
icon:FluentIcons.Brightness
|
icon:FluentIcons.Brightness
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Acrylic"
|
title:"Acrylic"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Acrylic.qml"
|
url:"qrc:/example/qml/page/T_Acrylic.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Theme"
|
title:"Theme"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Theme.qml"
|
url:"qrc:/example/qml/page/T_Theme.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Typography"
|
title:"Typography"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Typography.qml"
|
url:"qrc:/example/qml/page/T_Typography.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Awesome"
|
title:"Awesome"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Awesome.qml"
|
url:"qrc:/example/qml/page/T_Awesome.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluPaneItemExpander{
|
||||||
|
title: Lang.chart
|
||||||
|
icon:FluentIcons.AreaChart
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.bar_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_BarChart.qml"
|
||||||
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.line_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_LineChart.qml"
|
||||||
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.pie_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_PieChart.qml"
|
||||||
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.polar_area_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_PolarAreaChart.qml"
|
||||||
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.bubble_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_BubbleChart.qml"
|
||||||
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.scatter_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_ScatterChart.qml"
|
||||||
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.radar_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_RadarChart.qml"
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,56 +425,50 @@ FluObject{
|
|||||||
icon:FluentIcons.Shop
|
icon:FluentIcons.Shop
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"QRCode"
|
title:"QRCode"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_QRCode.qml"
|
url:"qrc:/example/qml/page/T_QRCode.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Tour"
|
title:"Tour"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Tour.qml"
|
url:"qrc:/example/qml/page/T_Tour.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Timeline"
|
title:"Timeline"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Timeline.qml"
|
url:"qrc:/example/qml/page/T_Timeline.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Screenshot(Todo)"
|
title:"Screenshot(Todo)"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Screenshot.qml"
|
url:"qrc:/example/qml/page/T_Screenshot.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Captcha"
|
title:"Captcha"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Captcha.qml"
|
url:"qrc:/example/qml/page/T_Captcha.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Chart"
|
title:"Network"
|
||||||
url:"qrc:/example/qml/page/T_Chart.qml"
|
menuDelegate: paneItemMenu
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
url:"qrc:/example/qml/page/T_Network.qml"
|
||||||
onTap:{ navigationView.push(url) }
|
|
||||||
}
|
|
||||||
FluPaneItem{
|
|
||||||
title:"Http"
|
|
||||||
url:"qrc:/example/qml/page/T_Http.qml"
|
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
id:item_other
|
id:item_other
|
||||||
title:"RemoteLoader"
|
title:"RemoteLoader"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
count: 99
|
count: 99
|
||||||
infoBadge:FluBadge{
|
infoBadge:FluBadge{
|
||||||
count: item_other.count
|
count: item_other.count
|
||||||
color: Qt.rgba(82/255,196/255,26/255,1)
|
color: Qt.rgba(82/255,196/255,26/255,1)
|
||||||
}
|
}
|
||||||
url:"qrc:/example/qml/page/T_RemoteLoader.qml"
|
url:"qrc:/example/qml/page/T_RemoteLoader.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{
|
onTap:{
|
||||||
item_other.count = 0
|
item_other.count = 0
|
||||||
navigationView.push("qrc:/example/qml/page/T_RemoteLoader.qml")
|
navigationView.push("qrc:/example/qml/page/T_RemoteLoader.qml")
|
||||||
@ -457,12 +479,11 @@ FluObject{
|
|||||||
onTapListener:function(){
|
onTapListener:function(){
|
||||||
FluApp.navigate("/hotload")
|
FluApp.navigate("/hotload")
|
||||||
}
|
}
|
||||||
onDropped:{ FluApp.navigate("/hotload") }
|
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"3D"
|
title:"3D"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_3D.qml"
|
url:"qrc:/example/qml/page/T_3D.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,14 @@ QtObject {
|
|||||||
property string locale
|
property string locale
|
||||||
property string navigation_view_display_mode
|
property string navigation_view_display_mode
|
||||||
property string other
|
property string other
|
||||||
|
property string chart
|
||||||
|
property string bar_chart
|
||||||
|
property string line_chart
|
||||||
|
property string pie_chart
|
||||||
|
property string polar_area_chart
|
||||||
|
property string bubble_chart
|
||||||
|
property string scatter_chart
|
||||||
|
property string radar_chart
|
||||||
|
|
||||||
function zh(){
|
function zh(){
|
||||||
home="首页"
|
home="首页"
|
||||||
@ -38,6 +46,14 @@ QtObject {
|
|||||||
locale="语言环境"
|
locale="语言环境"
|
||||||
navigation_view_display_mode="导航视图显示模式"
|
navigation_view_display_mode="导航视图显示模式"
|
||||||
other="其他"
|
other="其他"
|
||||||
|
chart="表格"
|
||||||
|
bar_chart="条形图"
|
||||||
|
line_chart="折线图"
|
||||||
|
pie_chart="饼图"
|
||||||
|
polar_area_chart="极坐标区域图"
|
||||||
|
bubble_chart="气泡图"
|
||||||
|
scatter_chart="散点图"
|
||||||
|
radar_chart="雷达图"
|
||||||
}
|
}
|
||||||
|
|
||||||
function en(){
|
function en(){
|
||||||
@ -57,6 +73,14 @@ QtObject {
|
|||||||
locale="Locale"
|
locale="Locale"
|
||||||
navigation_view_display_mode="NavigationView Display Mode"
|
navigation_view_display_mode="NavigationView Display Mode"
|
||||||
other="Other"
|
other="Other"
|
||||||
|
chart="Chart"
|
||||||
|
bar_chart="Bar Chart"
|
||||||
|
line_chart="Line Chart"
|
||||||
|
pie_chart="Pie Chart"
|
||||||
|
polar_area_chart="Polar Area Chart"
|
||||||
|
bubble_chart="Bubble Chart"
|
||||||
|
scatter_chart="Scatter Chart"
|
||||||
|
radar_chart="Radar Chart"
|
||||||
}
|
}
|
||||||
|
|
||||||
property string __locale
|
property string __locale
|
||||||
|
@ -43,6 +43,7 @@ FluScrollablePage{
|
|||||||
FluTextBox{
|
FluTextBox{
|
||||||
id:text_box
|
id:text_box
|
||||||
placeholderText: "请输入验证码"
|
placeholderText: "请输入验证码"
|
||||||
|
Layout.preferredWidth: 240
|
||||||
}
|
}
|
||||||
FluButton{
|
FluButton{
|
||||||
text:"verify"
|
text:"verify"
|
||||||
|
@ -1,331 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Window
|
|
||||||
import QtQuick.Controls
|
|
||||||
import FluentUI
|
|
||||||
import "qrc:///example/qml/component"
|
|
||||||
|
|
||||||
FluScrollablePage{
|
|
||||||
|
|
||||||
title:"Chart"
|
|
||||||
|
|
||||||
function randomScalingFactor() {
|
|
||||||
return Math.random().toFixed(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
FluArea{
|
|
||||||
height: 370
|
|
||||||
width: 500
|
|
||||||
paddings: 10
|
|
||||||
Layout.topMargin: 20
|
|
||||||
FluChart{
|
|
||||||
anchors.fill: parent
|
|
||||||
chartType: 'scatter'
|
|
||||||
chartData: {
|
|
||||||
return {
|
|
||||||
datasets: [{
|
|
||||||
label: 'My First dataset',
|
|
||||||
xAxisID: 'x-axis-1',
|
|
||||||
yAxisID: 'y-axis-1',
|
|
||||||
borderColor: '#ff5555',
|
|
||||||
backgroundColor: 'rgba(255,192,192,0.3)',
|
|
||||||
data: [{
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
label: 'My Second dataset',
|
|
||||||
xAxisID: 'x-axis-1',
|
|
||||||
yAxisID: 'y-axis-2',
|
|
||||||
borderColor: '#5555ff',
|
|
||||||
backgroundColor: 'rgba(192,192,255,0.3)',
|
|
||||||
data: [{
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}}
|
|
||||||
chartOptions: {return {
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
responsive: true,
|
|
||||||
hoverMode: 'nearest',
|
|
||||||
intersect: true,
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: 'Chart.js Scatter Chart - Multi Axis'
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
xAxes: [{
|
|
||||||
position: 'bottom',
|
|
||||||
gridLines: {
|
|
||||||
zeroLineColor: 'rgba(0,0,0,1)'
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
yAxes: [{
|
|
||||||
type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
|
|
||||||
display: true,
|
|
||||||
position: 'left',
|
|
||||||
id: 'y-axis-1',
|
|
||||||
}, {
|
|
||||||
type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
|
|
||||||
display: true,
|
|
||||||
position: 'right',
|
|
||||||
reverse: true,
|
|
||||||
id: 'y-axis-2',
|
|
||||||
|
|
||||||
// grid line settings
|
|
||||||
gridLines: {
|
|
||||||
drawOnChartArea: false, // only want the grid lines for one axis to show up
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluArea{
|
|
||||||
width: 500
|
|
||||||
height: 370
|
|
||||||
paddings: 10
|
|
||||||
Layout.topMargin: 20
|
|
||||||
FluChart{
|
|
||||||
anchors.fill: parent
|
|
||||||
chartType: 'bar'
|
|
||||||
chartData: { return {
|
|
||||||
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
|
||||||
datasets: [{
|
|
||||||
label: 'Dataset 1',
|
|
||||||
backgroundColor: '#ff9999',
|
|
||||||
stack: 'Stack 0',
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor()
|
|
||||||
]
|
|
||||||
}, {
|
|
||||||
label: 'Dataset 2',
|
|
||||||
backgroundColor: '#9999ff',
|
|
||||||
stack: 'Stack 0',
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor()
|
|
||||||
]
|
|
||||||
}, {
|
|
||||||
label: 'Dataset 3',
|
|
||||||
backgroundColor: '#99ff99',
|
|
||||||
stack: 'Stack 1',
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor()
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chartOptions: { return {
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: 'Chart.js Bar Chart - Stacked'
|
|
||||||
},
|
|
||||||
tooltips: {
|
|
||||||
mode: 'index',
|
|
||||||
intersect: false
|
|
||||||
},
|
|
||||||
responsive: true,
|
|
||||||
scales: {
|
|
||||||
xAxes: [{
|
|
||||||
stacked: true,
|
|
||||||
}],
|
|
||||||
yAxes: [{
|
|
||||||
stacked: true
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluArea{
|
|
||||||
width: 500
|
|
||||||
height: 370
|
|
||||||
paddings: 10
|
|
||||||
Layout.topMargin: 20
|
|
||||||
FluChart{
|
|
||||||
anchors.fill: parent
|
|
||||||
chartType: 'pie'
|
|
||||||
chartData: {return {
|
|
||||||
datasets: [{
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
],
|
|
||||||
backgroundColor: [
|
|
||||||
'#ffbbbb',
|
|
||||||
'#ffddaa',
|
|
||||||
'#ffffbb',
|
|
||||||
'#bbffbb',
|
|
||||||
'#bbbbff'
|
|
||||||
],
|
|
||||||
label: 'Dataset 1'
|
|
||||||
}],
|
|
||||||
labels: [
|
|
||||||
'Red',
|
|
||||||
'Orange',
|
|
||||||
'Yellow',
|
|
||||||
'Green',
|
|
||||||
'Blue'
|
|
||||||
]
|
|
||||||
}}
|
|
||||||
chartOptions: {return {maintainAspectRatio: false, responsive: true}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluArea{
|
|
||||||
width: 500
|
|
||||||
height: 370
|
|
||||||
paddings: 10
|
|
||||||
Layout.topMargin: 20
|
|
||||||
FluChart{
|
|
||||||
anchors.fill: parent
|
|
||||||
chartType: 'line'
|
|
||||||
chartData: { return {
|
|
||||||
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
|
||||||
datasets: [{
|
|
||||||
label: 'Filled',
|
|
||||||
fill: true,
|
|
||||||
backgroundColor: 'rgba(192,222,255,0.3)',
|
|
||||||
borderColor: 'rgba(128,192,255,255)',
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor()
|
|
||||||
],
|
|
||||||
}, {
|
|
||||||
label: 'Dashed',
|
|
||||||
fill: false,
|
|
||||||
backgroundColor: 'rgba(0,0,0,0)',
|
|
||||||
borderColor: '#009900',
|
|
||||||
borderDash: [5, 5],
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor()
|
|
||||||
],
|
|
||||||
}, {
|
|
||||||
label: 'Filled',
|
|
||||||
backgroundColor: 'rgba(0,0,0,0)',
|
|
||||||
borderColor: '#990000',
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor()
|
|
||||||
],
|
|
||||||
fill: false,
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chartOptions: {return {
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
responsive: true,
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: 'Chart.js Line Chart'
|
|
||||||
},
|
|
||||||
tooltips: {
|
|
||||||
mode: 'index',
|
|
||||||
intersect: false,
|
|
||||||
},
|
|
||||||
hover: {
|
|
||||||
mode: 'nearest',
|
|
||||||
intersect: true
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
xAxes: [{
|
|
||||||
display: true,
|
|
||||||
scaleLabel: {
|
|
||||||
display: true,
|
|
||||||
labelString: 'Month'
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
yAxes: [{
|
|
||||||
display: true,
|
|
||||||
scaleLabel: {
|
|
||||||
display: true,
|
|
||||||
labelString: 'Value'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -115,4 +115,68 @@ FluScrollablePage{
|
|||||||
showSuccess("点击最小化按钮")
|
showSuccess("点击最小化按钮")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 68
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluButton{
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
Layout.topMargin: 20
|
||||||
|
text:"Custom Content Dialog"
|
||||||
|
onClicked: {
|
||||||
|
custom_btn_dialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CodeExpander{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: -1
|
||||||
|
code:'FluContentDialog{
|
||||||
|
id:dialog
|
||||||
|
title:"友情提示"
|
||||||
|
message:"数据正在加载中,请稍等..."
|
||||||
|
negativeText:"取消加载"
|
||||||
|
contentDelegate: Component{
|
||||||
|
Item{
|
||||||
|
width: parent.width
|
||||||
|
height: 80
|
||||||
|
FluProgressRing{
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onNegativeClicked:{
|
||||||
|
showSuccess("点击取消按钮")
|
||||||
|
}
|
||||||
|
positiveText:"确定"
|
||||||
|
onPositiveClicked:{
|
||||||
|
showSuccess("点击确定按钮")
|
||||||
|
}
|
||||||
|
dialog.open()'
|
||||||
|
}
|
||||||
|
|
||||||
|
FluContentDialog{
|
||||||
|
id:custom_btn_dialog
|
||||||
|
title:"友情提示"
|
||||||
|
message:"数据正在加载中,请稍等..."
|
||||||
|
negativeText:"取消加载"
|
||||||
|
contentDelegate: Component{
|
||||||
|
Item{
|
||||||
|
width: parent.width
|
||||||
|
height: 80
|
||||||
|
FluProgressRing{
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onNegativeClicked:{
|
||||||
|
showSuccess("点击取消按钮")
|
||||||
|
}
|
||||||
|
positiveText:"确定"
|
||||||
|
onPositiveClicked:{
|
||||||
|
showSuccess("点击确定按钮")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ FluScrollablePage{
|
|||||||
Rectangle{
|
Rectangle{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: 5
|
radius: 5
|
||||||
color:FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03)
|
color:FluTheme.itemHoverColor
|
||||||
visible: item_mouse.containsMouse
|
visible: item_mouse.containsMouse
|
||||||
}
|
}
|
||||||
Rectangle{
|
Rectangle{
|
||||||
@ -172,17 +172,10 @@ FluScrollablePage{
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: 8
|
radius: 8
|
||||||
color:{
|
color:{
|
||||||
if(FluTheme.dark){
|
if(item_mouse.containsMouse){
|
||||||
if(item_mouse.containsMouse){
|
return FluTheme.itemHoverColor
|
||||||
return Qt.rgba(1,1,1,0.03)
|
|
||||||
}
|
|
||||||
return Qt.rgba(0,0,0,0)
|
|
||||||
}else{
|
|
||||||
if(item_mouse.containsMouse){
|
|
||||||
return Qt.rgba(0,0,0,0.03)
|
|
||||||
}
|
|
||||||
return Qt.rgba(0,0,0,0)
|
|
||||||
}
|
}
|
||||||
|
return FluTheme.itemNormalColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Image{
|
Image{
|
||||||
@ -227,7 +220,7 @@ FluScrollablePage{
|
|||||||
height: 12
|
height: 12
|
||||||
width: 12
|
width: 12
|
||||||
radius: 6
|
radius: 6
|
||||||
color: FluTheme.primaryColor.dark
|
color: FluTheme.primaryColor
|
||||||
anchors{
|
anchors{
|
||||||
right: parent.right
|
right: parent.right
|
||||||
top: parent.top
|
top: parent.top
|
||||||
|
@ -1,405 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Qt.labs.platform
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Window
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Dialogs
|
|
||||||
import FluentUI
|
|
||||||
import "qrc:///example/qml/component"
|
|
||||||
|
|
||||||
FluContentPage{
|
|
||||||
|
|
||||||
title:"Http"
|
|
||||||
property string cacheDirPath: StandardPaths.writableLocation(StandardPaths.AppLocalDataLocation) + "/cache/http"
|
|
||||||
property bool isDownCompleted: false
|
|
||||||
|
|
||||||
FluHttp{
|
|
||||||
id:http
|
|
||||||
cacheDir:cacheDirPath
|
|
||||||
}
|
|
||||||
|
|
||||||
FluHttp{
|
|
||||||
id:http_breakpoint_download
|
|
||||||
cacheDir:cacheDirPath
|
|
||||||
breakPointDownload: true
|
|
||||||
}
|
|
||||||
|
|
||||||
FluHttp{
|
|
||||||
id:http_cache_ifnonecacherequest
|
|
||||||
cacheMode:FluHttpType.IfNoneCacheRequest
|
|
||||||
cacheDir:cacheDirPath
|
|
||||||
}
|
|
||||||
|
|
||||||
FluHttp{
|
|
||||||
id:http_cache_requestfailedreadcache
|
|
||||||
cacheMode:FluHttpType.RequestFailedReadCache
|
|
||||||
cacheDir:cacheDirPath
|
|
||||||
}
|
|
||||||
|
|
||||||
FluHttp{
|
|
||||||
id:http_cache_firstcachethenrequest
|
|
||||||
cacheMode:FluHttpType.FirstCacheThenRequest
|
|
||||||
cacheDir:cacheDirPath
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpCallable{
|
|
||||||
id:callable
|
|
||||||
onStart: {
|
|
||||||
showLoading()
|
|
||||||
}
|
|
||||||
onFinish: {
|
|
||||||
hideLoading()
|
|
||||||
}
|
|
||||||
onError:
|
|
||||||
(status,errorString,result)=>{
|
|
||||||
console.debug(status+";"+errorString+";"+result)
|
|
||||||
}
|
|
||||||
onSuccess:
|
|
||||||
(result)=>{
|
|
||||||
text_info.text = result
|
|
||||||
}
|
|
||||||
onCache:
|
|
||||||
(result)=>{
|
|
||||||
text_info.text = result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Flickable{
|
|
||||||
id:layout_flick
|
|
||||||
width: 200
|
|
||||||
clip: true
|
|
||||||
anchors{
|
|
||||||
top: parent.top
|
|
||||||
topMargin: 20
|
|
||||||
bottom: parent.bottom
|
|
||||||
left: parent.left
|
|
||||||
}
|
|
||||||
ScrollBar.vertical: FluScrollBar {}
|
|
||||||
contentHeight:layout_column.height
|
|
||||||
Column{
|
|
||||||
spacing: 2
|
|
||||||
id:layout_column
|
|
||||||
width: parent.width
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "Get请求"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/get")
|
|
||||||
http.get(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "Post表单请求"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
var params = {}
|
|
||||||
params.custname = "朱子楚"
|
|
||||||
params.custtel = "1234567890"
|
|
||||||
params.custemail = "zhuzichu520@gmail.com"
|
|
||||||
request.params = params
|
|
||||||
var headers = {}
|
|
||||||
headers.test = "123456789456465321354"
|
|
||||||
request.headers = headers
|
|
||||||
http.post(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "Post Json请求"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
var params = {}
|
|
||||||
params.custname = "朱子楚"
|
|
||||||
params.custtel = "1234567890"
|
|
||||||
params.custemail = "zhuzichu520@gmail.com"
|
|
||||||
request.params = params
|
|
||||||
http.postJson(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "Post String请求"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
request.params = "我命由我不由天"
|
|
||||||
http.postString(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "Delete请求"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/delete")
|
|
||||||
http.deleteResource(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluProgressButton{
|
|
||||||
id:btn_download
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "下载文件"
|
|
||||||
onClicked: {
|
|
||||||
folder_dialog.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluProgressButton{
|
|
||||||
property bool downloading: false
|
|
||||||
id:btn_breakpoint_download
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: {
|
|
||||||
if(downloading){
|
|
||||||
return "暂停下载"
|
|
||||||
}
|
|
||||||
if(progress === 0){
|
|
||||||
return "断点下载文件"
|
|
||||||
}else if(progress === 1){
|
|
||||||
return "打开文件"
|
|
||||||
}else{
|
|
||||||
return "继续下载"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HttpRequest{
|
|
||||||
id:request_breakpoint_download
|
|
||||||
url: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
|
|
||||||
downloadSavePath: FluTools.getApplicationDirPath()+ "/download/big_buck_bunny.mp4"
|
|
||||||
}
|
|
||||||
HttpCallable{
|
|
||||||
id:callable_breakpoint_download
|
|
||||||
onStart: {
|
|
||||||
btn_breakpoint_download.downloading = true
|
|
||||||
}
|
|
||||||
onFinish: {
|
|
||||||
btn_breakpoint_download.downloading = false
|
|
||||||
}
|
|
||||||
onError:
|
|
||||||
(status,errorString,result)=>{
|
|
||||||
console.debug(status+";"+errorString+";"+result)
|
|
||||||
}
|
|
||||||
onSuccess:
|
|
||||||
(result)=>{
|
|
||||||
if(!isDownCompleted){
|
|
||||||
tour.open()
|
|
||||||
isDownCompleted = true
|
|
||||||
}
|
|
||||||
showSuccess(result)
|
|
||||||
}
|
|
||||||
onDownloadProgress:
|
|
||||||
(recv,total)=>{
|
|
||||||
btn_breakpoint_download.progress = recv/total
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
|
||||||
progress = http_breakpoint_download.getBreakPointProgress(request_breakpoint_download)
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
if(downloading){
|
|
||||||
http_breakpoint_download.cancel()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if(progress === 1){
|
|
||||||
FluTools.showFileInFolder(request_breakpoint_download.downloadSavePath)
|
|
||||||
}else{
|
|
||||||
http_breakpoint_download.download(request_breakpoint_download,callable_breakpoint_download)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluMenu{
|
|
||||||
id:menu_breakpoint_download
|
|
||||||
width: 120
|
|
||||||
FluMenuItem{
|
|
||||||
text: "删除文件"
|
|
||||||
onClicked: {
|
|
||||||
if(FluTools.removeFile(request_breakpoint_download.downloadSavePath)){
|
|
||||||
btn_breakpoint_download.progress = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.RightButton
|
|
||||||
onClicked: {
|
|
||||||
if(btn_breakpoint_download.progress === 1){
|
|
||||||
menu_breakpoint_download.popup()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluProgressButton{
|
|
||||||
id:btn_upload
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "文件上传"
|
|
||||||
onClicked: {
|
|
||||||
file_dialog.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "FirstCacheThenRequest缓存"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
request.params = {cacheMode:"FirstCacheThenRequest"}
|
|
||||||
http_cache_firstcachethenrequest.post(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "RequestFailedReadCache缓存"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
request.params = {cacheMode:"RequestFailedReadCache"}
|
|
||||||
http_cache_requestfailedreadcache.post(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "IfNoneCacheRequest缓存"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
request.params = {cacheMode:"IfNoneCacheRequest"}
|
|
||||||
http_cache_ifnonecacherequest.post(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "打开缓存路径"
|
|
||||||
onClicked: {
|
|
||||||
Qt.openUrlExternally(cacheDirPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "删除缓存"
|
|
||||||
onClicked: {
|
|
||||||
console.debug(FluTools.removeDir(cacheDirPath))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "清空右边数据"
|
|
||||||
onClicked: {
|
|
||||||
text_info.text = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluTour{
|
|
||||||
id:tour
|
|
||||||
steps:[
|
|
||||||
{title:"友情提示",description: "下载已完成,左击这里可以打开文件所在路径,右击可以弹出菜单删除文件!",target:()=>btn_breakpoint_download}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpCallable{
|
|
||||||
id:callable_upload
|
|
||||||
onStart: {
|
|
||||||
btn_upload.disabled = true
|
|
||||||
}
|
|
||||||
onFinish: {
|
|
||||||
btn_upload.disabled = false
|
|
||||||
}
|
|
||||||
onError:
|
|
||||||
(status,errorString,result)=>{
|
|
||||||
btn_upload.progress = 0
|
|
||||||
text_info.text = result
|
|
||||||
console.debug(result)
|
|
||||||
}
|
|
||||||
onSuccess:
|
|
||||||
(result)=>{
|
|
||||||
text_info.text = result
|
|
||||||
}
|
|
||||||
onUploadProgress:
|
|
||||||
(sent,total)=>{
|
|
||||||
btn_upload.progress = sent/total
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FileDialog {
|
|
||||||
id: file_dialog
|
|
||||||
onAccepted: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
var params = {}
|
|
||||||
for(var i=0;i<selectedFiles.length;i++){
|
|
||||||
var fileUrl = selectedFiles[i]
|
|
||||||
var fileName = FluTools.getFileNameByUrl(fileUrl)
|
|
||||||
var filePath = FluTools.toLocalPath(fileUrl)
|
|
||||||
params[fileName] = filePath
|
|
||||||
}
|
|
||||||
request.params = params
|
|
||||||
http.upload(request,callable_upload)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpCallable{
|
|
||||||
id:callable_download
|
|
||||||
onStart: {
|
|
||||||
btn_download.progress = 0
|
|
||||||
btn_download.disabled = true
|
|
||||||
}
|
|
||||||
onFinish: {
|
|
||||||
btn_download.disabled = false
|
|
||||||
}
|
|
||||||
onError:
|
|
||||||
(status,errorString,result)=>{
|
|
||||||
btn_download.progress = 0
|
|
||||||
showError(errorString)
|
|
||||||
console.debug(status+";"+errorString+";"+result)
|
|
||||||
}
|
|
||||||
onSuccess:
|
|
||||||
(result)=>{
|
|
||||||
showSuccess(result)
|
|
||||||
}
|
|
||||||
onDownloadProgress:
|
|
||||||
(recv,total)=>{
|
|
||||||
btn_download.progress = recv/total
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FolderDialog {
|
|
||||||
id: folder_dialog
|
|
||||||
currentFolder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]
|
|
||||||
onAccepted: {
|
|
||||||
var request = http.newRequest("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
|
|
||||||
request.downloadSavePath = FluTools.toLocalPath(currentFolder)+ "/big_buck_bunny.mp4"
|
|
||||||
http.download(request,callable_download)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluArea{
|
|
||||||
anchors{
|
|
||||||
top: layout_flick.top
|
|
||||||
bottom: layout_flick.bottom
|
|
||||||
left: layout_flick.right
|
|
||||||
right: parent.right
|
|
||||||
leftMargin: 8
|
|
||||||
}
|
|
||||||
Flickable{
|
|
||||||
clip: true
|
|
||||||
id:scrollview
|
|
||||||
boundsBehavior:Flickable.StopAtBounds
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
contentWidth: width
|
|
||||||
contentHeight: text_info.height
|
|
||||||
ScrollBar.vertical: FluScrollBar {}
|
|
||||||
FluText{
|
|
||||||
id:text_info
|
|
||||||
width: scrollview.width
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
padding: 14
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
560
example/qml-Qt6/page/T_Network.qml
Normal file
560
example/qml-Qt6/page/T_Network.qml
Normal file
@ -0,0 +1,560 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
import FluentUI
|
||||||
|
import Qt.labs.platform
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
|
||||||
|
FluContentPage{
|
||||||
|
|
||||||
|
id:root
|
||||||
|
title:"Network"
|
||||||
|
|
||||||
|
FluNetworkCallable{
|
||||||
|
id:callable
|
||||||
|
onStart: {
|
||||||
|
showLoading()
|
||||||
|
}
|
||||||
|
onFinish: {
|
||||||
|
hideLoading()
|
||||||
|
}
|
||||||
|
onError:
|
||||||
|
(status,errorString,result)=>{
|
||||||
|
console.debug(status+";"+errorString+";"+result)
|
||||||
|
}
|
||||||
|
onCache:
|
||||||
|
(result)=>{
|
||||||
|
text_info.text = result
|
||||||
|
}
|
||||||
|
onSuccess:
|
||||||
|
(result)=>{
|
||||||
|
text_info.text = result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Flickable{
|
||||||
|
id:layout_flick
|
||||||
|
width: 200
|
||||||
|
clip: true
|
||||||
|
anchors{
|
||||||
|
top: parent.top
|
||||||
|
topMargin: 20
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
}
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
|
contentHeight:layout_column.height
|
||||||
|
Column{
|
||||||
|
spacing: 2
|
||||||
|
id:layout_column
|
||||||
|
width: parent.width
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Get"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.get("https://httpbingo.org/get")
|
||||||
|
.addQuery("name","孙悟空")
|
||||||
|
.addQuery("age",500)
|
||||||
|
.addQuery("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Head"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.head("https://httpbingo.org/head")
|
||||||
|
.addQuery("name","孙悟空")
|
||||||
|
.addQuery("age",500)
|
||||||
|
.addQuery("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Post Body"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postBody("https://httpbingo.org/post")
|
||||||
|
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Post Form"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postForm("https://httpbingo.org/post")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Post JSON"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Post JSON Array"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJsonArray("https://httpbingo.org/post")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Put Body"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.putBody("https://httpbingo.org/put")
|
||||||
|
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Put Form"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.putForm("https://httpbingo.org/put")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Put JSON"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.putJson("https://httpbingo.org/put")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Put JSON Array"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.putJsonArray("https://httpbingo.org/put")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Patch Body"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.patchBody("https://httpbingo.org/patch")
|
||||||
|
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Patch Form"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.patchForm("https://httpbingo.org/patch")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Patch JSON"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.patchJson("https://httpbingo.org/patch")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Patch JSON Array"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.patchJsonArray("https://httpbingo.org/patch")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Delete Body"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.deleteBody("https://httpbingo.org/delete")
|
||||||
|
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Delete Form"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.deleteForm("https://httpbingo.org/delete")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Delete JSON"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.deleteJson("https://httpbingo.org/delete")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Delete JSON Array"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.deleteJsonArray("https://httpbingo.org/delete")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Open Log"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.openLog(true)
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Custom Header"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.addHeader("os","PC")
|
||||||
|
.addHeader("version","1.0.0")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "RequestFailedReadCache"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.setCacheMode(FluNetworkType.RequestFailedReadCache)
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.add("cacheMode","RequestFailedReadCache")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "IfNoneCacheRequest"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.setCacheMode(FluNetworkType.IfNoneCacheRequest)
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.add("cacheMode","IfNoneCacheRequest")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "FirstCacheThenRequest"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.setCacheMode(FluNetworkType.FirstCacheThenRequest)
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.add("cacheMode","FirstCacheThenRequest")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Timeout And Retry"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.setTimeout(5000)
|
||||||
|
.setRetry(3)
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.add("timeout","5000")
|
||||||
|
.add("retry","3")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluProgressButton{
|
||||||
|
id:btn_upload
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Upload File"
|
||||||
|
onClicked: {
|
||||||
|
file_dialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluProgressButton{
|
||||||
|
id:btn_download
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Download File"
|
||||||
|
onClicked: {
|
||||||
|
folder_dialog.showDialog(function(path){
|
||||||
|
FluNetwork.get("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
|
||||||
|
.toDownload(path)
|
||||||
|
.bind(root)
|
||||||
|
.go(callable_download_file)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluProgressButton{
|
||||||
|
id:btn_download_breakpoint
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Breakpoint Download File"
|
||||||
|
onClicked: {
|
||||||
|
folder_dialog.showDialog(function(path){
|
||||||
|
FluNetwork.get("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
|
||||||
|
.toDownload(path,true)
|
||||||
|
.bind(root)
|
||||||
|
.go(callable_breakpoint_download_file)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluNetworkCallable{
|
||||||
|
id:callable_upload_file
|
||||||
|
onStart: {
|
||||||
|
btn_upload.disabled = true
|
||||||
|
}
|
||||||
|
onFinish: {
|
||||||
|
btn_upload.disabled = false
|
||||||
|
}
|
||||||
|
onError:
|
||||||
|
(status,errorString,result)=>{
|
||||||
|
btn_upload.progress = 0
|
||||||
|
text_info.text = result
|
||||||
|
console.debug(status+";"+errorString+";"+result)
|
||||||
|
}
|
||||||
|
onSuccess:
|
||||||
|
(result)=>{
|
||||||
|
text_info.text = result
|
||||||
|
}
|
||||||
|
onUploadProgress:
|
||||||
|
(sent,total)=>{
|
||||||
|
btn_upload.progress = sent/total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluNetworkCallable{
|
||||||
|
id:callable_download_file
|
||||||
|
onStart: {
|
||||||
|
btn_download.progress = 0
|
||||||
|
btn_download.disabled = true
|
||||||
|
}
|
||||||
|
onFinish: {
|
||||||
|
btn_download.disabled = false
|
||||||
|
}
|
||||||
|
onError:
|
||||||
|
(status,errorString,result)=>{
|
||||||
|
btn_download.progress = 0
|
||||||
|
showError(errorString)
|
||||||
|
console.debug(status+";"+errorString+";"+result)
|
||||||
|
}
|
||||||
|
onSuccess:
|
||||||
|
(result)=>{
|
||||||
|
showSuccess(result)
|
||||||
|
}
|
||||||
|
onDownloadProgress:
|
||||||
|
(recv,total)=>{
|
||||||
|
btn_download.progress = recv/total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluNetworkCallable{
|
||||||
|
id:callable_breakpoint_download_file
|
||||||
|
onStart: {
|
||||||
|
btn_download_breakpoint.progress = 0
|
||||||
|
btn_download_breakpoint.disabled = true
|
||||||
|
}
|
||||||
|
onFinish: {
|
||||||
|
btn_download_breakpoint.disabled = false
|
||||||
|
}
|
||||||
|
onError:
|
||||||
|
(status,errorString,result)=>{
|
||||||
|
btn_download_breakpoint.progress = 0
|
||||||
|
showError(errorString)
|
||||||
|
console.debug(status+";"+errorString+";"+result)
|
||||||
|
}
|
||||||
|
onSuccess:
|
||||||
|
(result)=>{
|
||||||
|
showSuccess(result)
|
||||||
|
}
|
||||||
|
onDownloadProgress:
|
||||||
|
(recv,total)=>{
|
||||||
|
btn_download_breakpoint.progress = recv/total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDialog {
|
||||||
|
id: file_dialog
|
||||||
|
onAccepted: {
|
||||||
|
FluNetwork.postForm("https://httpbingo.org/post")
|
||||||
|
.setRetry(1)//只请求一次
|
||||||
|
.add("accessToken","12345678")
|
||||||
|
.addFile("file",FluTools.toLocalPath(file_dialog.currentFile))
|
||||||
|
.bind(root)
|
||||||
|
.go(callable_upload_file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDialog {
|
||||||
|
property var onSelectListener
|
||||||
|
id: folder_dialog
|
||||||
|
folder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]
|
||||||
|
currentFile: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]+"/big_buck_bunny.mp4"
|
||||||
|
fileMode: FileDialog.SaveFile
|
||||||
|
onAccepted: {
|
||||||
|
folder_dialog.onSelectListener(FluTools.toLocalPath(folder_dialog.currentFile))
|
||||||
|
}
|
||||||
|
function showDialog(listener){
|
||||||
|
folder_dialog.onSelectListener = listener
|
||||||
|
folder_dialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
anchors{
|
||||||
|
top: layout_flick.top
|
||||||
|
bottom: layout_flick.bottom
|
||||||
|
left: layout_flick.right
|
||||||
|
right: parent.right
|
||||||
|
leftMargin: 8
|
||||||
|
}
|
||||||
|
Flickable{
|
||||||
|
clip: true
|
||||||
|
id:scrollview
|
||||||
|
boundsBehavior:Flickable.StopAtBounds
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
contentWidth: width
|
||||||
|
contentHeight: text_info.height
|
||||||
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
|
FluText{
|
||||||
|
id:text_info
|
||||||
|
width: scrollview.width
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
padding: 14
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -31,6 +31,7 @@ FluScrollablePage{
|
|||||||
FluTextBox{
|
FluTextBox{
|
||||||
id:text_box
|
id:text_box
|
||||||
text:"会磨刀的小猪"
|
text:"会磨刀的小猪"
|
||||||
|
Layout.preferredWidth: 240
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ FluScrollablePage{
|
|||||||
color: FluTheme.dark ? FluColors.Black : FluColors.White
|
color: FluTheme.dark ? FluColors.Black : FluColors.White
|
||||||
FluShadow{
|
FluShadow{
|
||||||
radius: 4
|
radius: 4
|
||||||
color: FluTheme.primaryColor.dark
|
color: FluTheme.primaryColor
|
||||||
}
|
}
|
||||||
Image{
|
Image{
|
||||||
id:image
|
id:image
|
||||||
|
@ -62,16 +62,30 @@ FluScrollablePage{
|
|||||||
height: 50
|
height: 50
|
||||||
paddings: 10
|
paddings: 10
|
||||||
FluCheckBox{
|
FluCheckBox{
|
||||||
text:"V-Sync"
|
text:"Use System AppBar"
|
||||||
checked: FluApp.vsync
|
checked: FluApp.useSystemAppBar
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
onClicked: {
|
onClicked: {
|
||||||
FluApp.vsync = !FluApp.vsync
|
FluApp.useSystemAppBar = !FluApp.useSystemAppBar
|
||||||
dialog_restart.open()
|
dialog_restart.open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 20
|
||||||
|
height: 50
|
||||||
|
paddings: 10
|
||||||
|
FluCheckBox{
|
||||||
|
text:"fitsAppBarWindows"
|
||||||
|
checked: window.fitsAppBarWindows
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: {
|
||||||
|
window.fitsAppBarWindows = !window.fitsAppBarWindows
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FluArea{
|
FluArea{
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@ -199,5 +213,4 @@ FluScrollablePage{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
30
example/qml-Qt6/page/T_ShortcutPicker.qml
Normal file
30
example/qml-Qt6/page/T_ShortcutPicker.qml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Window
|
||||||
|
import FluentUI
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"ShortcutPicker"
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 20
|
||||||
|
height: 100
|
||||||
|
paddings: 10
|
||||||
|
FluShortcutPicker{
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CodeExpander{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: -1
|
||||||
|
code:'FluShortcutPicker{
|
||||||
|
|
||||||
|
}'
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -66,7 +66,7 @@ FluScrollablePage{
|
|||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color:FluTheme.primaryColor.dark
|
color:FluTheme.primaryColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ FluScrollablePage{
|
|||||||
statusMode: FluStatusViewType.Loading
|
statusMode: FluStatusViewType.Loading
|
||||||
Rectangle{
|
Rectangle{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color:FluTheme.primaryColor.dark
|
color:FluTheme.primaryColor
|
||||||
}
|
}
|
||||||
}'
|
}'
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ FluContentPage{
|
|||||||
iconSource: FluentIcons.ChevronUp
|
iconSource: FluentIcons.ChevronUp
|
||||||
iconColor: {
|
iconColor: {
|
||||||
if(1 === root.sortType){
|
if(1 === root.sortType){
|
||||||
return FluTheme.primaryColor.dark
|
return FluTheme.primaryColor
|
||||||
}
|
}
|
||||||
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
|
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
|
||||||
}
|
}
|
||||||
@ -202,7 +202,7 @@ FluContentPage{
|
|||||||
iconSource: FluentIcons.ChevronDown
|
iconSource: FluentIcons.ChevronDown
|
||||||
iconColor: {
|
iconColor: {
|
||||||
if(2 === root.sortType){
|
if(2 === root.sortType){
|
||||||
return FluTheme.primaryColor.dark
|
return FluTheme.primaryColor
|
||||||
}
|
}
|
||||||
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
|
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ FluScrollablePage{
|
|||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
iconSource: FluentIcons.AcceptMedium
|
iconSource: FluentIcons.AcceptMedium
|
||||||
iconSize: 15
|
iconSize: 15
|
||||||
visible: modelData === FluTheme.primaryColor
|
visible: modelData === FluTheme.themeColor
|
||||||
color: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
color: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||||
}
|
}
|
||||||
MouseArea{
|
MouseArea{
|
||||||
@ -40,7 +40,7 @@ FluScrollablePage{
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onClicked: {
|
onClicked: {
|
||||||
FluTheme.primaryColor = modelData
|
FluTheme.themeColor = modelData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ FluScrollablePage{
|
|||||||
CodeExpander{
|
CodeExpander{
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: -1
|
Layout.topMargin: -1
|
||||||
code:'FluTheme.primaryColor = FluColors.Orange
|
code:'FluTheme.themeColor = FluColors.Orange
|
||||||
|
|
||||||
FluTheme.dark = true
|
FluTheme.dark = true
|
||||||
|
|
||||||
|
@ -110,6 +110,7 @@ FluScrollablePage{
|
|||||||
FluTextBox{
|
FluTextBox{
|
||||||
id:text_box
|
id:text_box
|
||||||
text:"Technical testing 2015-09-01"
|
text:"Technical testing 2015-09-01"
|
||||||
|
Layout.preferredWidth: 240
|
||||||
}
|
}
|
||||||
FluFilledButton{
|
FluFilledButton{
|
||||||
text:"Append"
|
text:"Append"
|
||||||
|
@ -29,6 +29,7 @@ FluContentPage{
|
|||||||
FluTextBox{
|
FluTextBox{
|
||||||
id:text_box
|
id:text_box
|
||||||
text:"会磨刀的小猪"
|
text:"会磨刀的小猪"
|
||||||
|
Layout.preferredWidth: 240
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import FluentUI
|
|||||||
FluViewModel{
|
FluViewModel{
|
||||||
|
|
||||||
objectName: "SettingsViewModel"
|
objectName: "SettingsViewModel"
|
||||||
|
scope: FluViewModelType.Application
|
||||||
property int displayMode
|
property int displayMode
|
||||||
|
|
||||||
onInitData: {
|
onInitData: {
|
||||||
|
@ -60,11 +60,11 @@ FluWindow {
|
|||||||
event.accepted = false
|
event.accepted = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (event.urls.length !== 1) {
|
var url = getUrlByEvent(event)
|
||||||
|
if(url === ""){
|
||||||
event.accepted = false
|
event.accepted = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var url = event.urls[0].toString()
|
|
||||||
var fileExtension = url.substring(url.lastIndexOf(".") + 1)
|
var fileExtension = url.substring(url.lastIndexOf(".") + 1)
|
||||||
if (fileExtension !== "qml") {
|
if (fileExtension !== "qml") {
|
||||||
event.accepted = false
|
event.accepted = false
|
||||||
@ -74,12 +74,24 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
onDropped:
|
onDropped:
|
||||||
(event)=>{
|
(event)=>{
|
||||||
var path = event.urls[0].toString()
|
var url = getUrlByEvent(event)
|
||||||
loader.source = path
|
if(url !== ""){
|
||||||
watcher.path = path
|
loader.source = url
|
||||||
loader.reload()
|
watcher.path = url
|
||||||
|
loader.reload()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getUrlByEvent(event){
|
||||||
|
var url = ""
|
||||||
|
if (event.urls.length === 0) {
|
||||||
|
url = "file:///"+event.getDataAsString("text/plain")
|
||||||
|
}else{
|
||||||
|
url = event.urls[0].toString()
|
||||||
|
}
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,24 +13,25 @@ FluWindow {
|
|||||||
|
|
||||||
id:window
|
id:window
|
||||||
title: "FluentUI"
|
title: "FluentUI"
|
||||||
width: 1000
|
width: 960
|
||||||
height: 640
|
height: 600
|
||||||
closeDestory:false
|
|
||||||
minimumWidth: 520
|
minimumWidth: 520
|
||||||
minimumHeight: 200
|
minimumHeight: 200
|
||||||
launchMode: FluWindowType.SingleTask
|
launchMode: FluWindowType.SingleTask
|
||||||
|
fitsAppBarWindows: true
|
||||||
appBar: undefined
|
appBar: FluAppBar {
|
||||||
|
height: 30
|
||||||
|
darkText: Lang.dark_mode
|
||||||
|
showDark: true
|
||||||
|
darkClickListener:(button)=>handleDarkChanged(button)
|
||||||
|
closeClickListener: ()=>{dialog_close.open()}
|
||||||
|
z:7
|
||||||
|
}
|
||||||
|
|
||||||
SettingsViewModel{
|
SettingsViewModel{
|
||||||
id:viewmodel_settings
|
id:viewmodel_settings
|
||||||
}
|
}
|
||||||
|
|
||||||
closeListener:function(event){
|
|
||||||
dialog_close.open()
|
|
||||||
event.accepted = false
|
|
||||||
}
|
|
||||||
|
|
||||||
FluEvent{
|
FluEvent{
|
||||||
id:event_checkupdate
|
id:event_checkupdate
|
||||||
name: "checkUpdate"
|
name: "checkUpdate"
|
||||||
@ -38,9 +39,20 @@ FluWindow {
|
|||||||
checkUpdate(false)
|
checkUpdate(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onFirstVisible: {
|
||||||
|
timer_tour_delay.restart()
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer{
|
||||||
|
id:timer_tour_delay
|
||||||
|
interval: 200
|
||||||
|
onTriggered: {
|
||||||
|
tour.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
FluTools.setQuitOnLastWindowClosed(false)
|
|
||||||
tour.open()
|
|
||||||
checkUpdate(true)
|
checkUpdate(true)
|
||||||
FluEventBus.registerEvent(event_checkupdate)
|
FluEventBus.registerEvent(event_checkupdate)
|
||||||
}
|
}
|
||||||
@ -72,20 +84,43 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer{
|
||||||
|
id:timer_window_hide_delay
|
||||||
|
interval: 150
|
||||||
|
onTriggered: {
|
||||||
|
window.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FluContentDialog{
|
FluContentDialog{
|
||||||
id:dialog_close
|
id:dialog_close
|
||||||
title:"退出"
|
title:"退出"
|
||||||
message:"确定要退出程序吗?"
|
message:"确定要退出程序吗?"
|
||||||
negativeText:"最小化"
|
negativeText:"最小化"
|
||||||
buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.NeutralButton | FluContentDialogType.PositiveButton
|
buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.NeutralButton | FluContentDialogType.PositiveButton
|
||||||
onNegativeClicked:{
|
onNegativeClicked: {
|
||||||
window.hide()
|
|
||||||
system_tray.showMessage("友情提示","FluentUI已隐藏至托盘,点击托盘可再次激活窗口");
|
system_tray.showMessage("友情提示","FluentUI已隐藏至托盘,点击托盘可再次激活窗口");
|
||||||
|
timer_window_hide_delay.restart()
|
||||||
}
|
}
|
||||||
positiveText:"退出"
|
positiveText:"退出"
|
||||||
neutralText:"取消"
|
neutralText:"取消"
|
||||||
onPositiveClicked:{
|
onPositiveClicked:{
|
||||||
FluApp.exit()
|
FluApp.exit(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component{
|
||||||
|
id:nav_item_right_menu
|
||||||
|
FluMenu{
|
||||||
|
id:menu
|
||||||
|
width: 130
|
||||||
|
FluMenuItem{
|
||||||
|
text: "在独立窗口打开"
|
||||||
|
visible: true
|
||||||
|
onClicked: {
|
||||||
|
FluApp.navigate("/pageWindow",{title:modelData.title,url:modelData.url})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,18 +147,8 @@ FluWindow {
|
|||||||
back: Item{
|
back: Item{
|
||||||
anchors.fill: flipable
|
anchors.fill: flipable
|
||||||
visible: flipable.flipAngle !== 0
|
visible: flipable.flipAngle !== 0
|
||||||
FluAppBar {
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
darkText: Lang.dark_mode
|
|
||||||
showDark: true
|
|
||||||
z:7
|
|
||||||
darkClickListener:(button)=>handleDarkChanged(button)
|
|
||||||
}
|
|
||||||
Row{
|
Row{
|
||||||
|
id:layout_back_buttons
|
||||||
z:8
|
z:8
|
||||||
anchors{
|
anchors{
|
||||||
top: parent.top
|
top: parent.top
|
||||||
@ -154,25 +179,13 @@ FluWindow {
|
|||||||
id:loader
|
id:loader
|
||||||
lazy: true
|
lazy: true
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: "https://zhu-zichu.gitee.io/Qt6_156_LieflatPage.qml"
|
source: "https://zhu-zichu.gitee.io/Qt_163_LieflatPage.qml"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
front: Item{
|
front: Item{
|
||||||
id:page_front
|
id:page_front
|
||||||
visible: flipable.flipAngle !== 180
|
visible: flipable.flipAngle !== 180
|
||||||
anchors.fill: flipable
|
anchors.fill: flipable
|
||||||
FluAppBar {
|
|
||||||
id:app_bar_front
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
darkText: Lang.dark_mode
|
|
||||||
showDark: true
|
|
||||||
darkClickListener:(button)=>handleDarkChanged(button)
|
|
||||||
z:7
|
|
||||||
}
|
|
||||||
FluNavigationView{
|
FluNavigationView{
|
||||||
property int clickCount: 0
|
property int clickCount: 0
|
||||||
id:nav_view
|
id:nav_view
|
||||||
@ -185,7 +198,12 @@ FluWindow {
|
|||||||
pageMode: FluNavigationViewType.NoStack
|
pageMode: FluNavigationViewType.NoStack
|
||||||
items: ItemsOriginal
|
items: ItemsOriginal
|
||||||
footerItems:ItemsFooter
|
footerItems:ItemsFooter
|
||||||
topPadding:FluTools.isMacos() ? 20 : 0
|
topPadding:{
|
||||||
|
if(window.useSystemAppBar){
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return FluTools.isMacos() ? 20 : 0
|
||||||
|
}
|
||||||
displayMode:viewmodel_settings.displayMode
|
displayMode:viewmodel_settings.displayMode
|
||||||
logo: "qrc:/example/res/image/favicon.ico"
|
logo: "qrc:/example/res/image/favicon.ico"
|
||||||
title:"FluentUI"
|
title:"FluentUI"
|
||||||
@ -209,7 +227,9 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
ItemsOriginal.navigationView = nav_view
|
ItemsOriginal.navigationView = nav_view
|
||||||
|
ItemsOriginal.paneItemMenu = nav_item_right_menu
|
||||||
ItemsFooter.navigationView = nav_view
|
ItemsFooter.navigationView = nav_view
|
||||||
|
ItemsFooter.paneItemMenu = nav_item_right_menu
|
||||||
setCurrentIndex(0)
|
setCurrentIndex(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,7 +240,7 @@ FluWindow {
|
|||||||
id:com_reveal
|
id:com_reveal
|
||||||
CircularReveal{
|
CircularReveal{
|
||||||
id:reveal
|
id:reveal
|
||||||
target:window.contentItem
|
target:window.layoutContainer()
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onAnimationFinished:{
|
onAnimationFinished:{
|
||||||
//动画结束后释放资源
|
//动画结束后释放资源
|
||||||
@ -232,7 +252,7 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader{
|
FluLoader{
|
||||||
id:loader_reveal
|
id:loader_reveal
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
@ -242,11 +262,14 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleDarkChanged(button){
|
function handleDarkChanged(button){
|
||||||
if(FluTools.isMacos() || !FluTheme.enableAnimation){
|
if(!FluTheme.enableAnimation || window.fitsAppBarWindows === false){
|
||||||
changeDark()
|
changeDark()
|
||||||
}else{
|
}else{
|
||||||
|
if(loader_reveal.sourceComponent){
|
||||||
|
return
|
||||||
|
}
|
||||||
loader_reveal.sourceComponent = com_reveal
|
loader_reveal.sourceComponent = com_reveal
|
||||||
var target = window.contentItem
|
var target = window.layoutContainer()
|
||||||
var pos = button.mapToItem(target,0,0)
|
var pos = button.mapToItem(target,0,0)
|
||||||
var mouseX = pos.x
|
var mouseX = pos.x
|
||||||
var mouseY = pos.y
|
var mouseY = pos.y
|
||||||
@ -284,14 +307,14 @@ FluWindow {
|
|||||||
|
|
||||||
FluTour{
|
FluTour{
|
||||||
id:tour
|
id:tour
|
||||||
steps:[
|
steps:{
|
||||||
{title:"夜间模式",description: "这里可以切换夜间模式.",target:()=>app_bar_front.darkButton()},
|
var data = []
|
||||||
{title:"隐藏彩蛋",description: "多点几下试试!!",target:()=>nav_view.logoButton()}
|
if(!window.useSystemAppBar){
|
||||||
]
|
data.push({title:"夜间模式",description: "这里可以切换夜间模式.",target:()=>appBar.darkButton()})
|
||||||
}
|
}
|
||||||
|
data.push({title:"隐藏彩蛋",description: "多点几下试试!!",target:()=>nav_view.logoButton()})
|
||||||
FluHttp{
|
return data
|
||||||
id:http
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FpsItem{
|
FpsItem{
|
||||||
@ -323,7 +346,7 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpCallable{
|
FluNetworkCallable{
|
||||||
id:callable
|
id:callable
|
||||||
property bool silent: true
|
property bool silent: true
|
||||||
onStart: {
|
onStart: {
|
||||||
@ -359,8 +382,8 @@ FluWindow {
|
|||||||
|
|
||||||
function checkUpdate(silent){
|
function checkUpdate(silent){
|
||||||
callable.silent = silent
|
callable.silent = silent
|
||||||
var request = http.newRequest("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest")
|
FluNetwork.get("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest")
|
||||||
http.get(request,callable);
|
.go(callable)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ FluWindow {
|
|||||||
window.title = arg.title
|
window.title = arg.title
|
||||||
loader.setSource( arg.url,{animDisabled:true})
|
loader.setSource( arg.url,{animDisabled:true})
|
||||||
}
|
}
|
||||||
Loader{
|
FluLoader{
|
||||||
id: loader
|
id: loader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,8 @@ import QtQuick.Controls 2.15
|
|||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
import FluentUI 1.0
|
import FluentUI 1.0
|
||||||
|
|
||||||
Window {
|
Item {
|
||||||
id: app
|
id: app
|
||||||
flags: Qt.SplashScreen
|
|
||||||
|
|
||||||
Connections{
|
Connections{
|
||||||
target: FluTheme
|
target: FluTheme
|
||||||
@ -17,30 +16,19 @@ Window {
|
|||||||
|
|
||||||
Connections{
|
Connections{
|
||||||
target: FluApp
|
target: FluApp
|
||||||
function onVsyncChanged(){
|
function onUseSystemAppBarChanged(){
|
||||||
SettingsHelper.saveVsync(FluApp.vsync)
|
SettingsHelper.saveUseSystemAppBar(FluApp.useSystemAppBar)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluHttpInterceptor{
|
|
||||||
id:interceptor
|
|
||||||
function onIntercept(request){
|
|
||||||
if(request.method === "get"){
|
|
||||||
request.params["method"] = "get"
|
|
||||||
}
|
|
||||||
if(request.method === "post"){
|
|
||||||
request.params["method"] = "post"
|
|
||||||
}
|
|
||||||
request.headers["token"] ="yyds"
|
|
||||||
request.headers["os"] ="pc"
|
|
||||||
console.debug(JSON.stringify(request))
|
|
||||||
return request
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
FluNetwork.openLog = false
|
||||||
|
FluNetwork.setInterceptor(function(param){
|
||||||
|
param.addHeader("Token","000000000000000000000")
|
||||||
|
})
|
||||||
FluApp.init(app)
|
FluApp.init(app)
|
||||||
FluApp.vsync = SettingsHelper.getVsync()
|
FluApp.windowIcon = "qrc:/example/res/image/favicon.ico"
|
||||||
|
FluApp.useSystemAppBar = SettingsHelper.getUseSystemAppBar()
|
||||||
FluTheme.darkMode = SettingsHelper.getDarkMode()
|
FluTheme.darkMode = SettingsHelper.getDarkMode()
|
||||||
FluTheme.enableAnimation = true
|
FluTheme.enableAnimation = true
|
||||||
FluApp.routes = {
|
FluApp.routes = {
|
||||||
@ -54,7 +42,6 @@ Window {
|
|||||||
"/pageWindow":"qrc:/example/qml/window/PageWindow.qml"
|
"/pageWindow":"qrc:/example/qml/window/PageWindow.qml"
|
||||||
}
|
}
|
||||||
FluApp.initialRoute = "/"
|
FluApp.initialRoute = "/"
|
||||||
FluApp.httpInterceptor = interceptor
|
|
||||||
FluApp.run()
|
FluApp.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
133
example/qml/chart/T_BarChart.qml
Normal file
133
example/qml/chart/T_BarChart.qml
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import FluentUI 1.0
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
import "../component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Bar Chart"
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'bar'
|
||||||
|
chartData: { return {
|
||||||
|
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [65, 59, 80, 81, 56, 55, 40],
|
||||||
|
backgroundColor: [
|
||||||
|
'rgba(255, 99, 132, 0.2)',
|
||||||
|
'rgba(255, 159, 64, 0.2)',
|
||||||
|
'rgba(255, 205, 86, 0.2)',
|
||||||
|
'rgba(75, 192, 192, 0.2)',
|
||||||
|
'rgba(54, 162, 235, 0.2)',
|
||||||
|
'rgba(153, 102, 255, 0.2)',
|
||||||
|
'rgba(201, 203, 207, 0.2)'
|
||||||
|
],
|
||||||
|
borderColor: [
|
||||||
|
'rgb(255, 99, 132)',
|
||||||
|
'rgb(255, 159, 64)',
|
||||||
|
'rgb(255, 205, 86)',
|
||||||
|
'rgb(75, 192, 192)',
|
||||||
|
'rgb(54, 162, 235)',
|
||||||
|
'rgb(153, 102, 255)',
|
||||||
|
'rgb(201, 203, 207)'
|
||||||
|
],
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Bar Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
},
|
||||||
|
responsive: true,
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
stacked: true,
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
stacked: true
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'horizontalBar'
|
||||||
|
chartData: { return {
|
||||||
|
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [65, 59, 80, 81, 56, 55, 40],
|
||||||
|
backgroundColor: [
|
||||||
|
'rgba(255, 99, 132, 0.2)',
|
||||||
|
'rgba(255, 159, 64, 0.2)',
|
||||||
|
'rgba(255, 205, 86, 0.2)',
|
||||||
|
'rgba(75, 192, 192, 0.2)',
|
||||||
|
'rgba(54, 162, 235, 0.2)',
|
||||||
|
'rgba(153, 102, 255, 0.2)',
|
||||||
|
'rgba(201, 203, 207, 0.2)'
|
||||||
|
],
|
||||||
|
borderColor: [
|
||||||
|
'rgb(255, 99, 132)',
|
||||||
|
'rgb(255, 159, 64)',
|
||||||
|
'rgb(255, 205, 86)',
|
||||||
|
'rgb(75, 192, 192)',
|
||||||
|
'rgb(54, 162, 235)',
|
||||||
|
'rgb(153, 102, 255)',
|
||||||
|
'rgb(201, 203, 207)'
|
||||||
|
],
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js HorizontalBar Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
},
|
||||||
|
responsive: true,
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
stacked: true,
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
stacked: true
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
75
example/qml/chart/T_BubbleChart.qml
Normal file
75
example/qml/chart/T_BubbleChart.qml
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import FluentUI 1.0
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
import "../component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Bubble Chart"
|
||||||
|
|
||||||
|
function randomScalingFactor() {
|
||||||
|
return Math.random().toFixed(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
height: 370
|
||||||
|
width: 500
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'bubble'
|
||||||
|
chartData: {
|
||||||
|
return {
|
||||||
|
datasets: [{
|
||||||
|
label: 'First Dataset',
|
||||||
|
data: [{
|
||||||
|
x: 20,
|
||||||
|
y: 30,
|
||||||
|
r: 15
|
||||||
|
}, {
|
||||||
|
x: 12,
|
||||||
|
y: 70,
|
||||||
|
r: 20
|
||||||
|
}, {
|
||||||
|
x: 11,
|
||||||
|
y: 28,
|
||||||
|
r: 8
|
||||||
|
}, {
|
||||||
|
x: 9,
|
||||||
|
y: 28,
|
||||||
|
r: 10
|
||||||
|
}, {
|
||||||
|
x: 43,
|
||||||
|
y: 7,
|
||||||
|
r: 14
|
||||||
|
}, {
|
||||||
|
x: 22,
|
||||||
|
y: 22,
|
||||||
|
r: 12
|
||||||
|
}, {
|
||||||
|
x: 40,
|
||||||
|
y: 10,
|
||||||
|
r: 10
|
||||||
|
}],
|
||||||
|
backgroundColor: 'rgb(255, 99, 132)'
|
||||||
|
}]
|
||||||
|
}}
|
||||||
|
chartOptions: {return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
responsive: true,
|
||||||
|
hoverMode: 'nearest',
|
||||||
|
intersect: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Bubble Chart - Multi Axis'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
46
example/qml/chart/T_LineChart.qml
Normal file
46
example/qml/chart/T_LineChart.qml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import FluentUI 1.0
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
import "../component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Line Chart"
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'line'
|
||||||
|
chartData: { return {
|
||||||
|
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [65, 59, 80, 81, 56, 55, 40],
|
||||||
|
fill: false,
|
||||||
|
borderColor: 'rgb(75, 192, 192)',
|
||||||
|
tension: 0.1
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Line Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
94
example/qml/chart/T_PieChart.qml
Normal file
94
example/qml/chart/T_PieChart.qml
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import FluentUI 1.0
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
import "../component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Doughnut and Pie Chart"
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: "doughnut"
|
||||||
|
chartData: { return {
|
||||||
|
labels: [
|
||||||
|
'Red',
|
||||||
|
'Blue',
|
||||||
|
'Yellow'
|
||||||
|
],
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [300, 50, 100],
|
||||||
|
backgroundColor: [
|
||||||
|
'rgb(255, 99, 132)',
|
||||||
|
'rgb(54, 162, 235)',
|
||||||
|
'rgb(255, 205, 86)'
|
||||||
|
],
|
||||||
|
hoverOffset: 4
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Doughnut Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: "pie"
|
||||||
|
chartData: { return {
|
||||||
|
labels: [
|
||||||
|
'Red',
|
||||||
|
'Blue',
|
||||||
|
'Yellow'
|
||||||
|
],
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [300, 50, 100],
|
||||||
|
backgroundColor: [
|
||||||
|
'rgb(255, 99, 132)',
|
||||||
|
'rgb(54, 162, 235)',
|
||||||
|
'rgb(255, 205, 86)'
|
||||||
|
],
|
||||||
|
hoverOffset: 4
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Pie Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
58
example/qml/chart/T_PolarAreaChart.qml
Normal file
58
example/qml/chart/T_PolarAreaChart.qml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import FluentUI 1.0
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
import "../component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"PolarArea Chart"
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'polarArea'
|
||||||
|
chartData: { return {
|
||||||
|
labels: [
|
||||||
|
'Red',
|
||||||
|
'Green',
|
||||||
|
'Yellow',
|
||||||
|
'Grey',
|
||||||
|
'Blue'
|
||||||
|
],
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [11, 16, 7, 3, 14],
|
||||||
|
backgroundColor: [
|
||||||
|
'rgb(255, 99, 132)',
|
||||||
|
'rgb(75, 192, 192)',
|
||||||
|
'rgb(255, 205, 86)',
|
||||||
|
'rgb(201, 203, 207)',
|
||||||
|
'rgb(54, 162, 235)'
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js PolarArea Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
75
example/qml/chart/T_RadarChart.qml
Normal file
75
example/qml/chart/T_RadarChart.qml
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import FluentUI 1.0
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
import "../component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Radar Chart"
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
width: 500
|
||||||
|
height: 370
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'radar'
|
||||||
|
chartData: { return {
|
||||||
|
labels: [
|
||||||
|
'Eating',
|
||||||
|
'Drinking',
|
||||||
|
'Sleeping',
|
||||||
|
'Designing',
|
||||||
|
'Coding',
|
||||||
|
'Cycling',
|
||||||
|
'Running'
|
||||||
|
],
|
||||||
|
datasets:
|
||||||
|
[{
|
||||||
|
label: 'My First Dataset',
|
||||||
|
data: [65, 59, 90, 81, 56, 55, 40],
|
||||||
|
fill: true,
|
||||||
|
backgroundColor: 'rgba(255, 99, 132, 0.2)',
|
||||||
|
borderColor: 'rgb(255, 99, 132)',
|
||||||
|
pointBackgroundColor: 'rgb(255, 99, 132)',
|
||||||
|
pointBorderColor: '#fff',
|
||||||
|
pointHoverBackgroundColor: '#fff',
|
||||||
|
pointHoverBorderColor: 'rgb(255, 99, 132)'
|
||||||
|
}, {
|
||||||
|
label: 'My Second Dataset',
|
||||||
|
data: [28, 48, 40, 19, 96, 27, 100],
|
||||||
|
fill: true,
|
||||||
|
backgroundColor: 'rgba(54, 162, 235, 0.2)',
|
||||||
|
borderColor: 'rgb(54, 162, 235)',
|
||||||
|
pointBackgroundColor: 'rgb(54, 162, 235)',
|
||||||
|
pointBorderColor: '#fff',
|
||||||
|
pointHoverBackgroundColor: '#fff',
|
||||||
|
pointHoverBorderColor: 'rgb(54, 162, 235)'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chartOptions: { return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Radar Chart - Stacked'
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false
|
||||||
|
},
|
||||||
|
elements: {
|
||||||
|
line: {
|
||||||
|
borderWidth: 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
124
example/qml/chart/T_ScatterChart.qml
Normal file
124
example/qml/chart/T_ScatterChart.qml
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import FluentUI 1.0
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
import "../component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"Scatter Chart"
|
||||||
|
|
||||||
|
function randomScalingFactor() {
|
||||||
|
return Math.random().toFixed(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
height: 370
|
||||||
|
width: 500
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluChart{
|
||||||
|
anchors.fill: parent
|
||||||
|
chartType: 'scatter'
|
||||||
|
chartData: {
|
||||||
|
return {
|
||||||
|
datasets: [{
|
||||||
|
label: 'My First dataset',
|
||||||
|
xAxisID: 'x-axis-1',
|
||||||
|
yAxisID: 'y-axis-1',
|
||||||
|
borderColor: '#ff5555',
|
||||||
|
backgroundColor: 'rgba(255,192,192,0.3)',
|
||||||
|
data: [{
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
label: 'My Second dataset',
|
||||||
|
xAxisID: 'x-axis-1',
|
||||||
|
yAxisID: 'y-axis-2',
|
||||||
|
borderColor: '#5555ff',
|
||||||
|
backgroundColor: 'rgba(192,192,255,0.3)',
|
||||||
|
data: [{
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}, {
|
||||||
|
x: randomScalingFactor(),
|
||||||
|
y: randomScalingFactor(),
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}}
|
||||||
|
chartOptions: {return {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
responsive: true,
|
||||||
|
hoverMode: 'nearest',
|
||||||
|
intersect: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Chart.js Scatter Chart - Multi Axis'
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
position: 'bottom',
|
||||||
|
gridLines: {
|
||||||
|
zeroLineColor: 'rgba(0,0,0,1)'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
|
||||||
|
display: true,
|
||||||
|
position: 'left',
|
||||||
|
id: 'y-axis-1',
|
||||||
|
}, {
|
||||||
|
type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
|
||||||
|
display: true,
|
||||||
|
position: 'right',
|
||||||
|
reverse: true,
|
||||||
|
id: 'y-axis-2',
|
||||||
|
|
||||||
|
// grid line settings
|
||||||
|
gridLines: {
|
||||||
|
drawOnChartArea: false, // only want the grid lines for one axis to show up
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -130,7 +130,6 @@ FluExpander{
|
|||||||
"FluRadioButtons",
|
"FluRadioButtons",
|
||||||
"FluImage",
|
"FluImage",
|
||||||
"FluSpinBox",
|
"FluSpinBox",
|
||||||
"FluHttp",
|
|
||||||
"FluWatermark",
|
"FluWatermark",
|
||||||
"FluTour",
|
"FluTour",
|
||||||
"FluQRCode",
|
"FluQRCode",
|
||||||
@ -140,7 +139,9 @@ FluExpander{
|
|||||||
"FluStaggeredView",
|
"FluStaggeredView",
|
||||||
"FluProgressButton",
|
"FluProgressButton",
|
||||||
"FluLoadingButton",
|
"FluLoadingButton",
|
||||||
"FluClip"
|
"FluClip",
|
||||||
|
"FluNetwork",
|
||||||
|
"FluShortcutPicker"
|
||||||
];
|
];
|
||||||
code = code.replace(/\n/g, "<br>");
|
code = code.replace(/\n/g, "<br>");
|
||||||
code = code.replace(/ /g, " ");
|
code = code.replace(/ /g, " ");
|
||||||
|
@ -6,6 +6,7 @@ import FluentUI 1.0
|
|||||||
FluObject{
|
FluObject{
|
||||||
|
|
||||||
property var navigationView
|
property var navigationView
|
||||||
|
property var paneItemMenu
|
||||||
|
|
||||||
id:footer_items
|
id:footer_items
|
||||||
|
|
||||||
@ -14,7 +15,6 @@ FluObject{
|
|||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:Lang.about
|
title:Lang.about
|
||||||
icon:FluentIcons.Contact
|
icon:FluentIcons.Contact
|
||||||
onDropped: { FluApp.navigate("/about") }
|
|
||||||
onTapListener:function(){
|
onTapListener:function(){
|
||||||
FluApp.navigate("/about")
|
FluApp.navigate("/about")
|
||||||
}
|
}
|
||||||
@ -22,9 +22,9 @@ FluObject{
|
|||||||
|
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:Lang.settings
|
title:Lang.settings
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
icon:FluentIcons.Settings
|
icon:FluentIcons.Settings
|
||||||
url:"qrc:/example/qml/page/T_Settings.qml"
|
url:"qrc:/example/qml/page/T_Settings.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{
|
onTap:{
|
||||||
navigationView.push(url)
|
navigationView.push(url)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import FluentUI 1.0
|
|||||||
FluObject{
|
FluObject{
|
||||||
|
|
||||||
property var navigationView
|
property var navigationView
|
||||||
|
property var paneItemMenu
|
||||||
|
|
||||||
function rename(item, newName){
|
function rename(item, newName){
|
||||||
if(newName && newName.trim().length>0){
|
if(newName && newName.trim().length>0){
|
||||||
@ -17,32 +18,18 @@ FluObject{
|
|||||||
id:item_home
|
id:item_home
|
||||||
count: 9
|
count: 9
|
||||||
title:Lang.home
|
title:Lang.home
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
infoBadge:FluBadge{
|
infoBadge:FluBadge{
|
||||||
count: item_home.count
|
count: item_home.count
|
||||||
}
|
}
|
||||||
icon:FluentIcons.Home
|
icon:FluentIcons.Home
|
||||||
url:"qrc:/example/qml/page/T_Home.qml"
|
url:"qrc:/example/qml/page/T_Home.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{
|
onTap:{
|
||||||
if(navigationView.getCurrentUrl()){
|
if(navigationView.getCurrentUrl()){
|
||||||
item_home.count = 0
|
item_home.count = 0
|
||||||
}
|
}
|
||||||
navigationView.push(url)
|
navigationView.push(url)
|
||||||
}
|
}
|
||||||
editDelegate: FluTextBox{
|
|
||||||
text:item_home.title
|
|
||||||
}
|
|
||||||
menuDelegate: FluMenu{
|
|
||||||
id:nav_item_right_menu
|
|
||||||
width: 120
|
|
||||||
FluMenuItem{
|
|
||||||
text: "重命名"
|
|
||||||
visible: true
|
|
||||||
onClicked: {
|
|
||||||
item_home.showEdit = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FluPaneItemExpander{
|
FluPaneItemExpander{
|
||||||
@ -55,18 +42,6 @@ FluObject{
|
|||||||
id:item_expander_basic_input
|
id:item_expander_basic_input
|
||||||
title:Lang.basic_input
|
title:Lang.basic_input
|
||||||
icon:FluentIcons.CheckboxComposite
|
icon:FluentIcons.CheckboxComposite
|
||||||
editDelegate: FluTextBox{
|
|
||||||
text:item_expander_basic_input.title
|
|
||||||
}
|
|
||||||
menuDelegate: FluMenu{
|
|
||||||
FluMenuItem{
|
|
||||||
text: "重命名"
|
|
||||||
visible: true
|
|
||||||
onClicked: {
|
|
||||||
item_expander_basic_input.showEdit = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
id:item_buttons
|
id:item_buttons
|
||||||
count: 99
|
count: 99
|
||||||
@ -74,11 +49,11 @@ FluObject{
|
|||||||
count: item_buttons.count
|
count: item_buttons.count
|
||||||
}
|
}
|
||||||
title:"Buttons"
|
title:"Buttons"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/Button.png"
|
image:"qrc:/example/res/image/control/Button.png"
|
||||||
recentlyUpdated:true
|
recentlyUpdated:true
|
||||||
desc:"A control that responds to user input and raisesa Click event."
|
desc:"A control that responds to user input and raisesa Click event."
|
||||||
url:"qrc:/example/qml/page/T_Buttons.qml"
|
url:"qrc:/example/qml/page/T_Buttons.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{
|
onTap:{
|
||||||
item_buttons.count = 0
|
item_buttons.count = 0
|
||||||
navigationView.push(url)
|
navigationView.push(url)
|
||||||
@ -87,13 +62,13 @@ FluObject{
|
|||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
id:item_text
|
id:item_text
|
||||||
title:"Text"
|
title:"Text"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
count: 5
|
count: 5
|
||||||
infoBadge:FluBadge{
|
infoBadge:FluBadge{
|
||||||
count: item_text.count
|
count: item_text.count
|
||||||
color: Qt.rgba(82/255,196/255,26/255,1)
|
color: Qt.rgba(82/255,196/255,26/255,1)
|
||||||
}
|
}
|
||||||
url:"qrc:/example/qml/page/T_Text.qml"
|
url:"qrc:/example/qml/page/T_Text.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{
|
onTap:{
|
||||||
item_text.count = 0
|
item_text.count = 0
|
||||||
navigationView.push(url)
|
navigationView.push(url)
|
||||||
@ -101,38 +76,38 @@ FluObject{
|
|||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Image"
|
title:"Image"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Image.qml"
|
url:"qrc:/example/qml/page/T_Image.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Slider"
|
title:"Slider"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/Slider.png"
|
image:"qrc:/example/res/image/control/Slider.png"
|
||||||
recentlyUpdated:true
|
recentlyUpdated:true
|
||||||
desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack."
|
desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack."
|
||||||
url:"qrc:/example/qml/page/T_Slider.qml"
|
url:"qrc:/example/qml/page/T_Slider.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"CheckBox"
|
title:"CheckBox"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/Checkbox.png"
|
image:"qrc:/example/res/image/control/Checkbox.png"
|
||||||
recentlyUpdated:true
|
recentlyUpdated:true
|
||||||
desc:"A control that a user can select or clear."
|
desc:"A control that a user can select or clear."
|
||||||
url:"qrc:/example/qml/page/T_CheckBox.qml"
|
url:"qrc:/example/qml/page/T_CheckBox.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"RadioButton"
|
title:"RadioButton"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_RadioButton.qml"
|
url:"qrc:/example/qml/page/T_RadioButton.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"ToggleSwitch"
|
title:"ToggleSwitch"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_ToggleSwitch.qml"
|
url:"qrc:/example/qml/page/T_ToggleSwitch.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
@ -147,32 +122,38 @@ FluObject{
|
|||||||
icon:FluentIcons.GridView
|
icon:FluentIcons.GridView
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"TextBox"
|
title:"TextBox"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_TextBox.qml"
|
url:"qrc:/example/qml/page/T_TextBox.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"TimePicker"
|
title:"TimePicker"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_TimePicker.qml"
|
url:"qrc:/example/qml/page/T_TimePicker.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"DatePicker"
|
title:"DatePicker"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_DatePicker.qml"
|
url:"qrc:/example/qml/page/T_DatePicker.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"CalendarPicker"
|
title:"CalendarPicker"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_CalendarPicker.qml"
|
url:"qrc:/example/qml/page/T_CalendarPicker.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"ColorPicker"
|
title:"ColorPicker"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_ColorPicker.qml"
|
url:"qrc:/example/qml/page/T_ColorPicker.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:"ShortcutPicker"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/page/T_ShortcutPicker.qml"
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,71 +163,71 @@ FluObject{
|
|||||||
icon:FluentIcons.SurfaceHub
|
icon:FluentIcons.SurfaceHub
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"InfoBar"
|
title:"InfoBar"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/InfoBar.png"
|
image:"qrc:/example/res/image/control/InfoBar.png"
|
||||||
recentlyUpdated:true
|
recentlyUpdated:true
|
||||||
desc:"An inline message to display app-wide statuschange information."
|
desc:"An inline message to display app-wide statuschange information."
|
||||||
url:"qrc:/example/qml/page/T_InfoBar.qml"
|
url:"qrc:/example/qml/page/T_InfoBar.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Progress"
|
title:"Progress"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Progress.qml"
|
url:"qrc:/example/qml/page/T_Progress.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"RatingControl"
|
title:"RatingControl"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_RatingControl.qml"
|
url:"qrc:/example/qml/page/T_RatingControl.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Badge"
|
title:"Badge"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Badge.qml"
|
url:"qrc:/example/qml/page/T_Badge.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Rectangle"
|
title:"Rectangle"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Rectangle.qml"
|
url:"qrc:/example/qml/page/T_Rectangle.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Clip"
|
title:"Clip"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Clip.qml"
|
url:"qrc:/example/qml/page/T_Clip.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"StatusView"
|
title:"StatusView"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_StatusView.qml"
|
url:"qrc:/example/qml/page/T_StatusView.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Carousel"
|
title:"Carousel"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Carousel.qml"
|
url:"qrc:/example/qml/page/T_Carousel.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Expander"
|
title:"Expander"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Expander.qml"
|
url:"qrc:/example/qml/page/T_Expander.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"StaggeredView"
|
title:"StaggeredView"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_StaggeredView.qml"
|
url:"qrc:/example/qml/page/T_StaggeredView.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Watermark"
|
title:"Watermark"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Watermark.qml"
|
url:"qrc:/example/qml/page/T_Watermark.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,20 +237,20 @@ FluObject{
|
|||||||
icon:FluentIcons.ButtonMenu
|
icon:FluentIcons.ButtonMenu
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Dialog"
|
title:"Dialog"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Dialog.qml"
|
url:"qrc:/example/qml/page/T_Dialog.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
id:item_combobox
|
id:item_combobox
|
||||||
title:"ComboBox"
|
title:"ComboBox"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
count: 9
|
count: 9
|
||||||
infoBadge:FluBadge{
|
infoBadge:FluBadge{
|
||||||
count: item_combobox.count
|
count: item_combobox.count
|
||||||
color: Qt.rgba(250/255,173/255,20/255,1)
|
color: Qt.rgba(250/255,173/255,20/255,1)
|
||||||
}
|
}
|
||||||
url:"qrc:/example/qml/page/T_ComboBox.qml"
|
url:"qrc:/example/qml/page/T_ComboBox.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{
|
onTap:{
|
||||||
item_combobox.count = 0
|
item_combobox.count = 0
|
||||||
navigationView.push("qrc:/example/qml/page/T_ComboBox.qml")
|
navigationView.push("qrc:/example/qml/page/T_ComboBox.qml")
|
||||||
@ -277,14 +258,14 @@ FluObject{
|
|||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Tooltip"
|
title:"Tooltip"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Tooltip.qml"
|
url:"qrc:/example/qml/page/T_Tooltip.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Menu"
|
title:"Menu"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Menu.qml"
|
url:"qrc:/example/qml/page/T_Menu.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,66 +275,66 @@ FluObject{
|
|||||||
icon:FluentIcons.AllApps
|
icon:FluentIcons.AllApps
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Pivot"
|
title:"Pivot"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/Pivot.png"
|
image:"qrc:/example/res/image/control/Pivot.png"
|
||||||
recentlyAdded:true
|
recentlyAdded:true
|
||||||
order:3
|
order:3
|
||||||
desc:"Presents information from different sources in atabbed view."
|
desc:"Presents information from different sources in atabbed view."
|
||||||
url:"qrc:/example/qml/page/T_Pivot.qml"
|
url:"qrc:/example/qml/page/T_Pivot.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"BreadcrumbBar"
|
title:"BreadcrumbBar"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_BreadcrumbBar.qml"
|
url:"qrc:/example/qml/page/T_BreadcrumbBar.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"TabView"
|
title:"TabView"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/TabView.png"
|
image:"qrc:/example/res/image/control/TabView.png"
|
||||||
recentlyAdded:true
|
recentlyAdded:true
|
||||||
order:1
|
order:1
|
||||||
desc:"A control that displays a collection of tabs thatcan be used to display several documents."
|
desc:"A control that displays a collection of tabs thatcan be used to display several documents."
|
||||||
url:"qrc:/example/qml/page/T_TabView.qml"
|
url:"qrc:/example/qml/page/T_TabView.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"TreeView"
|
title:"TreeView"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_TreeView.qml"
|
url:"qrc:/example/qml/page/T_TreeView.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"TableView"
|
title:"TableView"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/DataGrid.png"
|
image:"qrc:/example/res/image/control/DataGrid.png"
|
||||||
recentlyAdded:true
|
recentlyAdded:true
|
||||||
order:4
|
order:4
|
||||||
desc:"The TableView control provides a flexible way to display a collection of data in rows and columns"
|
desc:"The TableView control provides a flexible way to display a collection of data in rows and columns"
|
||||||
url:"qrc:/example/qml/page/T_TableView.qml"
|
url:"qrc:/example/qml/page/T_TableView.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Pagination"
|
title:"Pagination"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Pagination.qml"
|
url:"qrc:/example/qml/page/T_Pagination.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"MultiWindow"
|
title:"MultiWindow"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_MultiWindow.qml"
|
url:"qrc:/example/qml/page/T_MultiWindow.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"FlipView"
|
title:"FlipView"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
image:"qrc:/example/res/image/control/FlipView.png"
|
image:"qrc:/example/res/image/control/FlipView.png"
|
||||||
recentlyAdded:true
|
recentlyAdded:true
|
||||||
order:2
|
order:2
|
||||||
desc:"Presents a collection of items that the user canflip through, one item at a time."
|
desc:"Presents a collection of items that the user canflip through, one item at a time."
|
||||||
url:"qrc:/example/qml/page/T_FlipView.qml"
|
url:"qrc:/example/qml/page/T_FlipView.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,26 +344,73 @@ FluObject{
|
|||||||
icon:FluentIcons.Brightness
|
icon:FluentIcons.Brightness
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Acrylic"
|
title:"Acrylic"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Acrylic.qml"
|
url:"qrc:/example/qml/page/T_Acrylic.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Theme"
|
title:"Theme"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Theme.qml"
|
url:"qrc:/example/qml/page/T_Theme.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Typography"
|
title:"Typography"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Typography.qml"
|
url:"qrc:/example/qml/page/T_Typography.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Awesome"
|
title:"Awesome"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Awesome.qml"
|
url:"qrc:/example/qml/page/T_Awesome.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluPaneItemExpander{
|
||||||
|
title: Lang.chart
|
||||||
|
icon:FluentIcons.AreaChart
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.bar_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_BarChart.qml"
|
||||||
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.line_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_LineChart.qml"
|
||||||
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.pie_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_PieChart.qml"
|
||||||
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.polar_area_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_PolarAreaChart.qml"
|
||||||
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.bubble_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_BubbleChart.qml"
|
||||||
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.scatter_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_ScatterChart.qml"
|
||||||
|
onTap:{ navigationView.push(url) }
|
||||||
|
}
|
||||||
|
FluPaneItem{
|
||||||
|
title:Lang.radar_chart
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
|
url:"qrc:/example/qml/chart/T_RadarChart.qml"
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,56 +425,50 @@ FluObject{
|
|||||||
icon:FluentIcons.Shop
|
icon:FluentIcons.Shop
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"QRCode"
|
title:"QRCode"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_QRCode.qml"
|
url:"qrc:/example/qml/page/T_QRCode.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Tour"
|
title:"Tour"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Tour.qml"
|
url:"qrc:/example/qml/page/T_Tour.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Timeline"
|
title:"Timeline"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Timeline.qml"
|
url:"qrc:/example/qml/page/T_Timeline.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Screenshot(Todo)"
|
title:"Screenshot(Todo)"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Screenshot.qml"
|
url:"qrc:/example/qml/page/T_Screenshot.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Captcha"
|
title:"Captcha"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_Captcha.qml"
|
url:"qrc:/example/qml/page/T_Captcha.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"Chart"
|
title:"Network"
|
||||||
url:"qrc:/example/qml/page/T_Chart.qml"
|
menuDelegate: paneItemMenu
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
url:"qrc:/example/qml/page/T_Network.qml"
|
||||||
onTap:{ navigationView.push(url) }
|
|
||||||
}
|
|
||||||
FluPaneItem{
|
|
||||||
title:"Http"
|
|
||||||
url:"qrc:/example/qml/page/T_Http.qml"
|
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
id:item_other
|
id:item_other
|
||||||
title:"RemoteLoader"
|
title:"RemoteLoader"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
count: 99
|
count: 99
|
||||||
infoBadge:FluBadge{
|
infoBadge:FluBadge{
|
||||||
count: item_other.count
|
count: item_other.count
|
||||||
color: Qt.rgba(82/255,196/255,26/255,1)
|
color: Qt.rgba(82/255,196/255,26/255,1)
|
||||||
}
|
}
|
||||||
url:"qrc:/example/qml/page/T_RemoteLoader.qml"
|
url:"qrc:/example/qml/page/T_RemoteLoader.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{
|
onTap:{
|
||||||
item_other.count = 0
|
item_other.count = 0
|
||||||
navigationView.push("qrc:/example/qml/page/T_RemoteLoader.qml")
|
navigationView.push("qrc:/example/qml/page/T_RemoteLoader.qml")
|
||||||
@ -457,12 +479,11 @@ FluObject{
|
|||||||
onTapListener:function(){
|
onTapListener:function(){
|
||||||
FluApp.navigate("/hotload")
|
FluApp.navigate("/hotload")
|
||||||
}
|
}
|
||||||
onDropped:{ FluApp.navigate("/hotload") }
|
|
||||||
}
|
}
|
||||||
FluPaneItem{
|
FluPaneItem{
|
||||||
title:"3D"
|
title:"3D"
|
||||||
|
menuDelegate: paneItemMenu
|
||||||
url:"qrc:/example/qml/page/T_3D.qml"
|
url:"qrc:/example/qml/page/T_3D.qml"
|
||||||
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
|
|
||||||
onTap:{ navigationView.push(url) }
|
onTap:{ navigationView.push(url) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,14 @@ QtObject {
|
|||||||
property string locale
|
property string locale
|
||||||
property string navigation_view_display_mode
|
property string navigation_view_display_mode
|
||||||
property string other
|
property string other
|
||||||
|
property string chart
|
||||||
|
property string bar_chart
|
||||||
|
property string line_chart
|
||||||
|
property string pie_chart
|
||||||
|
property string polar_area_chart
|
||||||
|
property string bubble_chart
|
||||||
|
property string scatter_chart
|
||||||
|
property string radar_chart
|
||||||
|
|
||||||
function zh(){
|
function zh(){
|
||||||
home="首页"
|
home="首页"
|
||||||
@ -38,6 +46,14 @@ QtObject {
|
|||||||
locale="语言环境"
|
locale="语言环境"
|
||||||
navigation_view_display_mode="导航视图显示模式"
|
navigation_view_display_mode="导航视图显示模式"
|
||||||
other="其他"
|
other="其他"
|
||||||
|
chart="表格"
|
||||||
|
bar_chart="条形图"
|
||||||
|
line_chart="折线图"
|
||||||
|
pie_chart="饼图"
|
||||||
|
polar_area_chart="极坐标区域图"
|
||||||
|
bubble_chart="气泡图"
|
||||||
|
scatter_chart="散点图"
|
||||||
|
radar_chart="雷达图"
|
||||||
}
|
}
|
||||||
|
|
||||||
function en(){
|
function en(){
|
||||||
@ -57,6 +73,14 @@ QtObject {
|
|||||||
locale="Locale"
|
locale="Locale"
|
||||||
navigation_view_display_mode="NavigationView Display Mode"
|
navigation_view_display_mode="NavigationView Display Mode"
|
||||||
other="Other"
|
other="Other"
|
||||||
|
chart="Chart"
|
||||||
|
bar_chart="Bar Chart"
|
||||||
|
line_chart="Line Chart"
|
||||||
|
pie_chart="Pie Chart"
|
||||||
|
polar_area_chart="Polar Area Chart"
|
||||||
|
bubble_chart="Bubble Chart"
|
||||||
|
scatter_chart="Scatter Chart"
|
||||||
|
radar_chart="Radar Chart"
|
||||||
}
|
}
|
||||||
|
|
||||||
property string __locale
|
property string __locale
|
||||||
|
@ -44,6 +44,7 @@ FluScrollablePage{
|
|||||||
FluTextBox{
|
FluTextBox{
|
||||||
id:text_box
|
id:text_box
|
||||||
placeholderText: "请输入验证码"
|
placeholderText: "请输入验证码"
|
||||||
|
Layout.preferredWidth: 240
|
||||||
}
|
}
|
||||||
FluButton{
|
FluButton{
|
||||||
text:"verify"
|
text:"verify"
|
||||||
|
@ -1,332 +0,0 @@
|
|||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
import QtQuick.Window 2.15
|
|
||||||
import QtQuick.Controls 2.15
|
|
||||||
import FluentUI 1.0
|
|
||||||
import "qrc:///example/qml/component"
|
|
||||||
import "../component"
|
|
||||||
|
|
||||||
FluScrollablePage{
|
|
||||||
|
|
||||||
title:"Chart"
|
|
||||||
|
|
||||||
function randomScalingFactor() {
|
|
||||||
return Math.random().toFixed(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
FluArea{
|
|
||||||
height: 370
|
|
||||||
width: 500
|
|
||||||
paddings: 10
|
|
||||||
Layout.topMargin: 20
|
|
||||||
FluChart{
|
|
||||||
anchors.fill: parent
|
|
||||||
chartType: 'scatter'
|
|
||||||
chartData: {
|
|
||||||
return {
|
|
||||||
datasets: [{
|
|
||||||
label: 'My First dataset',
|
|
||||||
xAxisID: 'x-axis-1',
|
|
||||||
yAxisID: 'y-axis-1',
|
|
||||||
borderColor: '#ff5555',
|
|
||||||
backgroundColor: 'rgba(255,192,192,0.3)',
|
|
||||||
data: [{
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
label: 'My Second dataset',
|
|
||||||
xAxisID: 'x-axis-1',
|
|
||||||
yAxisID: 'y-axis-2',
|
|
||||||
borderColor: '#5555ff',
|
|
||||||
backgroundColor: 'rgba(192,192,255,0.3)',
|
|
||||||
data: [{
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}, {
|
|
||||||
x: randomScalingFactor(),
|
|
||||||
y: randomScalingFactor(),
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}}
|
|
||||||
chartOptions: {return {
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
responsive: true,
|
|
||||||
hoverMode: 'nearest',
|
|
||||||
intersect: true,
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: 'Chart.js Scatter Chart - Multi Axis'
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
xAxes: [{
|
|
||||||
position: 'bottom',
|
|
||||||
gridLines: {
|
|
||||||
zeroLineColor: 'rgba(0,0,0,1)'
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
yAxes: [{
|
|
||||||
type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
|
|
||||||
display: true,
|
|
||||||
position: 'left',
|
|
||||||
id: 'y-axis-1',
|
|
||||||
}, {
|
|
||||||
type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
|
|
||||||
display: true,
|
|
||||||
position: 'right',
|
|
||||||
reverse: true,
|
|
||||||
id: 'y-axis-2',
|
|
||||||
|
|
||||||
// grid line settings
|
|
||||||
gridLines: {
|
|
||||||
drawOnChartArea: false, // only want the grid lines for one axis to show up
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluArea{
|
|
||||||
width: 500
|
|
||||||
height: 370
|
|
||||||
paddings: 10
|
|
||||||
Layout.topMargin: 20
|
|
||||||
FluChart{
|
|
||||||
anchors.fill: parent
|
|
||||||
chartType: 'bar'
|
|
||||||
chartData: { return {
|
|
||||||
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
|
||||||
datasets: [{
|
|
||||||
label: 'Dataset 1',
|
|
||||||
backgroundColor: '#ff9999',
|
|
||||||
stack: 'Stack 0',
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor()
|
|
||||||
]
|
|
||||||
}, {
|
|
||||||
label: 'Dataset 2',
|
|
||||||
backgroundColor: '#9999ff',
|
|
||||||
stack: 'Stack 0',
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor()
|
|
||||||
]
|
|
||||||
}, {
|
|
||||||
label: 'Dataset 3',
|
|
||||||
backgroundColor: '#99ff99',
|
|
||||||
stack: 'Stack 1',
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor()
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chartOptions: { return {
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: 'Chart.js Bar Chart - Stacked'
|
|
||||||
},
|
|
||||||
tooltips: {
|
|
||||||
mode: 'index',
|
|
||||||
intersect: false
|
|
||||||
},
|
|
||||||
responsive: true,
|
|
||||||
scales: {
|
|
||||||
xAxes: [{
|
|
||||||
stacked: true,
|
|
||||||
}],
|
|
||||||
yAxes: [{
|
|
||||||
stacked: true
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluArea{
|
|
||||||
width: 500
|
|
||||||
height: 370
|
|
||||||
paddings: 10
|
|
||||||
Layout.topMargin: 20
|
|
||||||
FluChart{
|
|
||||||
anchors.fill: parent
|
|
||||||
chartType: 'pie'
|
|
||||||
chartData: {return {
|
|
||||||
datasets: [{
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
],
|
|
||||||
backgroundColor: [
|
|
||||||
'#ffbbbb',
|
|
||||||
'#ffddaa',
|
|
||||||
'#ffffbb',
|
|
||||||
'#bbffbb',
|
|
||||||
'#bbbbff'
|
|
||||||
],
|
|
||||||
label: 'Dataset 1'
|
|
||||||
}],
|
|
||||||
labels: [
|
|
||||||
'Red',
|
|
||||||
'Orange',
|
|
||||||
'Yellow',
|
|
||||||
'Green',
|
|
||||||
'Blue'
|
|
||||||
]
|
|
||||||
}}
|
|
||||||
chartOptions: {return {maintainAspectRatio: false, responsive: true}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluArea{
|
|
||||||
width: 500
|
|
||||||
height: 370
|
|
||||||
paddings: 10
|
|
||||||
Layout.topMargin: 20
|
|
||||||
FluChart{
|
|
||||||
anchors.fill: parent
|
|
||||||
chartType: 'line'
|
|
||||||
chartData: { return {
|
|
||||||
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
|
|
||||||
datasets: [{
|
|
||||||
label: 'Filled',
|
|
||||||
fill: true,
|
|
||||||
backgroundColor: 'rgba(192,222,255,0.3)',
|
|
||||||
borderColor: 'rgba(128,192,255,255)',
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor()
|
|
||||||
],
|
|
||||||
}, {
|
|
||||||
label: 'Dashed',
|
|
||||||
fill: false,
|
|
||||||
backgroundColor: 'rgba(0,0,0,0)',
|
|
||||||
borderColor: '#009900',
|
|
||||||
borderDash: [5, 5],
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor()
|
|
||||||
],
|
|
||||||
}, {
|
|
||||||
label: 'Filled',
|
|
||||||
backgroundColor: 'rgba(0,0,0,0)',
|
|
||||||
borderColor: '#990000',
|
|
||||||
data: [
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor(),
|
|
||||||
randomScalingFactor()
|
|
||||||
],
|
|
||||||
fill: false,
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chartOptions: {return {
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
responsive: true,
|
|
||||||
title: {
|
|
||||||
display: true,
|
|
||||||
text: 'Chart.js Line Chart'
|
|
||||||
},
|
|
||||||
tooltips: {
|
|
||||||
mode: 'index',
|
|
||||||
intersect: false,
|
|
||||||
},
|
|
||||||
hover: {
|
|
||||||
mode: 'nearest',
|
|
||||||
intersect: true
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
xAxes: [{
|
|
||||||
display: true,
|
|
||||||
scaleLabel: {
|
|
||||||
display: true,
|
|
||||||
labelString: 'Month'
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
yAxes: [{
|
|
||||||
display: true,
|
|
||||||
scaleLabel: {
|
|
||||||
display: true,
|
|
||||||
labelString: 'Value'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -116,4 +116,68 @@ FluScrollablePage{
|
|||||||
showSuccess("点击最小化按钮")
|
showSuccess("点击最小化按钮")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 68
|
||||||
|
paddings: 10
|
||||||
|
Layout.topMargin: 20
|
||||||
|
FluButton{
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
Layout.topMargin: 20
|
||||||
|
text:"Custom Content Dialog"
|
||||||
|
onClicked: {
|
||||||
|
custom_btn_dialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CodeExpander{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: -1
|
||||||
|
code:'FluContentDialog{
|
||||||
|
id:dialog
|
||||||
|
title:"友情提示"
|
||||||
|
message:"数据正在加载中,请稍等..."
|
||||||
|
negativeText:"取消加载"
|
||||||
|
contentDelegate: Component{
|
||||||
|
Item{
|
||||||
|
width: parent.width
|
||||||
|
height: 80
|
||||||
|
FluProgressRing{
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onNegativeClicked:{
|
||||||
|
showSuccess("点击取消按钮")
|
||||||
|
}
|
||||||
|
positiveText:"确定"
|
||||||
|
onPositiveClicked:{
|
||||||
|
showSuccess("点击确定按钮")
|
||||||
|
}
|
||||||
|
dialog.open()'
|
||||||
|
}
|
||||||
|
|
||||||
|
FluContentDialog{
|
||||||
|
id:custom_btn_dialog
|
||||||
|
title:"友情提示"
|
||||||
|
message:"数据正在加载中,请稍等..."
|
||||||
|
negativeText:"取消加载"
|
||||||
|
contentDelegate: Component{
|
||||||
|
Item{
|
||||||
|
width: parent.width
|
||||||
|
height: 80
|
||||||
|
FluProgressRing{
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onNegativeClicked:{
|
||||||
|
showSuccess("点击取消按钮")
|
||||||
|
}
|
||||||
|
positiveText:"确定"
|
||||||
|
onPositiveClicked:{
|
||||||
|
showSuccess("点击确定按钮")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ import QtQuick 2.15
|
|||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
import QtQuick.Window 2.15
|
import QtQuick.Window 2.15
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
import QtGraphicalEffects 1.0
|
|
||||||
import "qrc:///example/qml/global"
|
import "qrc:///example/qml/global"
|
||||||
import FluentUI 1.0
|
import FluentUI 1.0
|
||||||
|
|
||||||
@ -78,7 +77,7 @@ FluScrollablePage{
|
|||||||
Rectangle{
|
Rectangle{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: 5
|
radius: 5
|
||||||
color:FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03)
|
color:FluTheme.itemHoverColor
|
||||||
visible: item_mouse.containsMouse
|
visible: item_mouse.containsMouse
|
||||||
}
|
}
|
||||||
Rectangle{
|
Rectangle{
|
||||||
@ -173,17 +172,10 @@ FluScrollablePage{
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: 8
|
radius: 8
|
||||||
color:{
|
color:{
|
||||||
if(FluTheme.dark){
|
if(item_mouse.containsMouse){
|
||||||
if(item_mouse.containsMouse){
|
return FluTheme.itemHoverColor
|
||||||
return Qt.rgba(1,1,1,0.03)
|
|
||||||
}
|
|
||||||
return Qt.rgba(0,0,0,0)
|
|
||||||
}else{
|
|
||||||
if(item_mouse.containsMouse){
|
|
||||||
return Qt.rgba(0,0,0,0.03)
|
|
||||||
}
|
|
||||||
return Qt.rgba(0,0,0,0)
|
|
||||||
}
|
}
|
||||||
|
return FluTheme.itemNormalColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Image{
|
Image{
|
||||||
@ -228,7 +220,7 @@ FluScrollablePage{
|
|||||||
height: 12
|
height: 12
|
||||||
width: 12
|
width: 12
|
||||||
radius: 6
|
radius: 6
|
||||||
color: FluTheme.primaryColor.dark
|
color: FluTheme.primaryColor
|
||||||
anchors{
|
anchors{
|
||||||
right: parent.right
|
right: parent.right
|
||||||
top: parent.top
|
top: parent.top
|
||||||
|
@ -1,406 +0,0 @@
|
|||||||
import QtQuick 2.15
|
|
||||||
import Qt.labs.platform 1.1
|
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
import QtQuick.Window 2.15
|
|
||||||
import QtQuick.Controls 2.15
|
|
||||||
import QtQuick.Dialogs 1.3
|
|
||||||
import FluentUI 1.0
|
|
||||||
import "qrc:///example/qml/component"
|
|
||||||
import "../component"
|
|
||||||
|
|
||||||
FluContentPage{
|
|
||||||
|
|
||||||
title:"Http"
|
|
||||||
property string cacheDirPath: StandardPaths.writableLocation(StandardPaths.AppLocalDataLocation) + "/cache/http"
|
|
||||||
property bool isDownCompleted: false
|
|
||||||
|
|
||||||
FluHttp{
|
|
||||||
id:http
|
|
||||||
cacheDir:cacheDirPath
|
|
||||||
}
|
|
||||||
|
|
||||||
FluHttp{
|
|
||||||
id:http_breakpoint_download
|
|
||||||
cacheDir:cacheDirPath
|
|
||||||
breakPointDownload: true
|
|
||||||
}
|
|
||||||
|
|
||||||
FluHttp{
|
|
||||||
id:http_cache_ifnonecacherequest
|
|
||||||
cacheMode:FluHttpType.IfNoneCacheRequest
|
|
||||||
cacheDir:cacheDirPath
|
|
||||||
}
|
|
||||||
|
|
||||||
FluHttp{
|
|
||||||
id:http_cache_requestfailedreadcache
|
|
||||||
cacheMode:FluHttpType.RequestFailedReadCache
|
|
||||||
cacheDir:cacheDirPath
|
|
||||||
}
|
|
||||||
|
|
||||||
FluHttp{
|
|
||||||
id:http_cache_firstcachethenrequest
|
|
||||||
cacheMode:FluHttpType.FirstCacheThenRequest
|
|
||||||
cacheDir:cacheDirPath
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpCallable{
|
|
||||||
id:callable
|
|
||||||
onStart: {
|
|
||||||
showLoading()
|
|
||||||
}
|
|
||||||
onFinish: {
|
|
||||||
hideLoading()
|
|
||||||
}
|
|
||||||
onError:
|
|
||||||
(status,errorString,result)=>{
|
|
||||||
console.debug(status+";"+errorString+";"+result)
|
|
||||||
}
|
|
||||||
onSuccess:
|
|
||||||
(result)=>{
|
|
||||||
text_info.text = result
|
|
||||||
}
|
|
||||||
onCache:
|
|
||||||
(result)=>{
|
|
||||||
text_info.text = result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Flickable{
|
|
||||||
id:layout_flick
|
|
||||||
width: 200
|
|
||||||
clip: true
|
|
||||||
anchors{
|
|
||||||
top: parent.top
|
|
||||||
topMargin: 20
|
|
||||||
bottom: parent.bottom
|
|
||||||
left: parent.left
|
|
||||||
}
|
|
||||||
ScrollBar.vertical: FluScrollBar {}
|
|
||||||
contentHeight:layout_column.height
|
|
||||||
Column{
|
|
||||||
spacing: 2
|
|
||||||
id:layout_column
|
|
||||||
width: parent.width
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "Get请求"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/get")
|
|
||||||
http.get(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "Post表单请求"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
var params = {}
|
|
||||||
params.custname = "朱子楚"
|
|
||||||
params.custtel = "1234567890"
|
|
||||||
params.custemail = "zhuzichu520@gmail.com"
|
|
||||||
request.params = params
|
|
||||||
var headers = {}
|
|
||||||
headers.test = "123456789456465321354"
|
|
||||||
request.headers = headers
|
|
||||||
http.post(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "Post Json请求"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
var params = {}
|
|
||||||
params.custname = "朱子楚"
|
|
||||||
params.custtel = "1234567890"
|
|
||||||
params.custemail = "zhuzichu520@gmail.com"
|
|
||||||
request.params = params
|
|
||||||
http.postJson(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "Post String请求"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
request.params = "我命由我不由天"
|
|
||||||
http.postString(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "Delete请求"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/delete")
|
|
||||||
http.deleteResource(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluProgressButton{
|
|
||||||
id:btn_download
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "下载文件"
|
|
||||||
onClicked: {
|
|
||||||
folder_dialog.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluProgressButton{
|
|
||||||
property bool downloading: false
|
|
||||||
id:btn_breakpoint_download
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: {
|
|
||||||
if(downloading){
|
|
||||||
return "暂停下载"
|
|
||||||
}
|
|
||||||
if(progress === 0){
|
|
||||||
return "断点下载文件"
|
|
||||||
}else if(progress === 1){
|
|
||||||
return "打开文件"
|
|
||||||
}else{
|
|
||||||
return "继续下载"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HttpRequest{
|
|
||||||
id:request_breakpoint_download
|
|
||||||
url: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
|
|
||||||
downloadSavePath: FluTools.getApplicationDirPath()+ "/download/big_buck_bunny.mp4"
|
|
||||||
}
|
|
||||||
HttpCallable{
|
|
||||||
id:callable_breakpoint_download
|
|
||||||
onStart: {
|
|
||||||
btn_breakpoint_download.downloading = true
|
|
||||||
}
|
|
||||||
onFinish: {
|
|
||||||
btn_breakpoint_download.downloading = false
|
|
||||||
}
|
|
||||||
onError:
|
|
||||||
(status,errorString,result)=>{
|
|
||||||
console.debug(status+";"+errorString+";"+result)
|
|
||||||
}
|
|
||||||
onSuccess:
|
|
||||||
(result)=>{
|
|
||||||
if(!isDownCompleted){
|
|
||||||
tour.open()
|
|
||||||
isDownCompleted = true
|
|
||||||
}
|
|
||||||
showSuccess(result)
|
|
||||||
}
|
|
||||||
onDownloadProgress:
|
|
||||||
(recv,total)=>{
|
|
||||||
btn_breakpoint_download.progress = recv/total
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
|
||||||
progress = http_breakpoint_download.getBreakPointProgress(request_breakpoint_download)
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
if(downloading){
|
|
||||||
http_breakpoint_download.cancel()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if(progress === 1){
|
|
||||||
FluTools.showFileInFolder(request_breakpoint_download.downloadSavePath)
|
|
||||||
}else{
|
|
||||||
http_breakpoint_download.download(request_breakpoint_download,callable_breakpoint_download)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluMenu{
|
|
||||||
id:menu_breakpoint_download
|
|
||||||
width: 120
|
|
||||||
FluMenuItem{
|
|
||||||
text: "删除文件"
|
|
||||||
onClicked: {
|
|
||||||
if(FluTools.removeFile(request_breakpoint_download.downloadSavePath)){
|
|
||||||
btn_breakpoint_download.progress = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.RightButton
|
|
||||||
onClicked: {
|
|
||||||
if(btn_breakpoint_download.progress === 1){
|
|
||||||
menu_breakpoint_download.popup()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluProgressButton{
|
|
||||||
id:btn_upload
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "文件上传"
|
|
||||||
onClicked: {
|
|
||||||
file_dialog.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "FirstCacheThenRequest缓存"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
request.params = {cacheMode:"FirstCacheThenRequest"}
|
|
||||||
http_cache_firstcachethenrequest.post(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "RequestFailedReadCache缓存"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
request.params = {cacheMode:"RequestFailedReadCache"}
|
|
||||||
http_cache_requestfailedreadcache.post(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "IfNoneCacheRequest缓存"
|
|
||||||
onClicked: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
request.params = {cacheMode:"IfNoneCacheRequest"}
|
|
||||||
http_cache_ifnonecacherequest.post(request,callable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "打开缓存路径"
|
|
||||||
onClicked: {
|
|
||||||
Qt.openUrlExternally(cacheDirPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "删除缓存"
|
|
||||||
onClicked: {
|
|
||||||
console.debug(FluTools.removeDir(cacheDirPath))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluButton{
|
|
||||||
implicitWidth: parent.width
|
|
||||||
implicitHeight: 36
|
|
||||||
text: "清空右边数据"
|
|
||||||
onClicked: {
|
|
||||||
text_info.text = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FluTour{
|
|
||||||
id:tour
|
|
||||||
steps:[
|
|
||||||
{title:"友情提示",description: "下载已完成,左击这里可以打开文件所在路径,右击可以弹出菜单删除文件!",target:()=>btn_breakpoint_download}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpCallable{
|
|
||||||
id:callable_upload
|
|
||||||
onStart: {
|
|
||||||
btn_upload.disabled = true
|
|
||||||
}
|
|
||||||
onFinish: {
|
|
||||||
btn_upload.disabled = false
|
|
||||||
}
|
|
||||||
onError:
|
|
||||||
(status,errorString,result)=>{
|
|
||||||
btn_upload.progress = 0
|
|
||||||
text_info.text = result
|
|
||||||
console.debug(result)
|
|
||||||
}
|
|
||||||
onSuccess:
|
|
||||||
(result)=>{
|
|
||||||
text_info.text = result
|
|
||||||
}
|
|
||||||
onUploadProgress:
|
|
||||||
(sent,total)=>{
|
|
||||||
btn_upload.progress = sent/total
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FileDialog {
|
|
||||||
id: file_dialog
|
|
||||||
onAccepted: {
|
|
||||||
var request = http.newRequest("https://httpbingo.org/post")
|
|
||||||
var params = {}
|
|
||||||
for(var i=0;i<selectedFiles.length;i++){
|
|
||||||
var fileUrl = selectedFiles[i]
|
|
||||||
var fileName = FluTools.getFileNameByUrl(fileUrl)
|
|
||||||
var filePath = FluTools.toLocalPath(fileUrl)
|
|
||||||
params[fileName] = filePath
|
|
||||||
}
|
|
||||||
request.params = params
|
|
||||||
http.upload(request,callable_upload)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpCallable{
|
|
||||||
id:callable_download
|
|
||||||
onStart: {
|
|
||||||
btn_download.progress = 0
|
|
||||||
btn_download.disabled = true
|
|
||||||
}
|
|
||||||
onFinish: {
|
|
||||||
btn_download.disabled = false
|
|
||||||
}
|
|
||||||
onError:
|
|
||||||
(status,errorString,result)=>{
|
|
||||||
btn_download.progress = 0
|
|
||||||
showError(errorString)
|
|
||||||
console.debug(status+";"+errorString+";"+result)
|
|
||||||
}
|
|
||||||
onSuccess:
|
|
||||||
(result)=>{
|
|
||||||
showSuccess(result)
|
|
||||||
}
|
|
||||||
onDownloadProgress:
|
|
||||||
(recv,total)=>{
|
|
||||||
btn_download.progress = recv/total
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FolderDialog {
|
|
||||||
id: folder_dialog
|
|
||||||
currentFolder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]
|
|
||||||
onAccepted: {
|
|
||||||
var request = http.newRequest("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
|
|
||||||
request.downloadSavePath = FluTools.toLocalPath(currentFolder)+ "/big_buck_bunny.mp4"
|
|
||||||
http.download(request,callable_download)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FluArea{
|
|
||||||
anchors{
|
|
||||||
top: layout_flick.top
|
|
||||||
bottom: layout_flick.bottom
|
|
||||||
left: layout_flick.right
|
|
||||||
right: parent.right
|
|
||||||
leftMargin: 8
|
|
||||||
}
|
|
||||||
Flickable{
|
|
||||||
clip: true
|
|
||||||
id:scrollview
|
|
||||||
boundsBehavior:Flickable.StopAtBounds
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
contentWidth: width
|
|
||||||
contentHeight: text_info.height
|
|
||||||
ScrollBar.vertical: FluScrollBar {}
|
|
||||||
FluText{
|
|
||||||
id:text_info
|
|
||||||
width: scrollview.width
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
padding: 14
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
561
example/qml/page/T_Network.qml
Normal file
561
example/qml/page/T_Network.qml
Normal file
@ -0,0 +1,561 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import FluentUI 1.0
|
||||||
|
import Qt.labs.platform 1.0
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
import "../component"
|
||||||
|
|
||||||
|
FluContentPage{
|
||||||
|
|
||||||
|
id:root
|
||||||
|
title:"Network"
|
||||||
|
|
||||||
|
FluNetworkCallable{
|
||||||
|
id:callable
|
||||||
|
onStart: {
|
||||||
|
showLoading()
|
||||||
|
}
|
||||||
|
onFinish: {
|
||||||
|
hideLoading()
|
||||||
|
}
|
||||||
|
onError:
|
||||||
|
(status,errorString,result)=>{
|
||||||
|
console.debug(status+";"+errorString+";"+result)
|
||||||
|
}
|
||||||
|
onCache:
|
||||||
|
(result)=>{
|
||||||
|
text_info.text = result
|
||||||
|
}
|
||||||
|
onSuccess:
|
||||||
|
(result)=>{
|
||||||
|
text_info.text = result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Flickable{
|
||||||
|
id:layout_flick
|
||||||
|
width: 200
|
||||||
|
clip: true
|
||||||
|
anchors{
|
||||||
|
top: parent.top
|
||||||
|
topMargin: 20
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
}
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
|
contentHeight:layout_column.height
|
||||||
|
Column{
|
||||||
|
spacing: 2
|
||||||
|
id:layout_column
|
||||||
|
width: parent.width
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Get"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.get("https://httpbingo.org/get")
|
||||||
|
.addQuery("name","孙悟空")
|
||||||
|
.addQuery("age",500)
|
||||||
|
.addQuery("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Head"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.head("https://httpbingo.org/head")
|
||||||
|
.addQuery("name","孙悟空")
|
||||||
|
.addQuery("age",500)
|
||||||
|
.addQuery("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Post Body"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postBody("https://httpbingo.org/post")
|
||||||
|
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Post Form"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postForm("https://httpbingo.org/post")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Post JSON"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Post JSON Array"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJsonArray("https://httpbingo.org/post")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Put Body"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.putBody("https://httpbingo.org/put")
|
||||||
|
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Put Form"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.putForm("https://httpbingo.org/put")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Put JSON"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.putJson("https://httpbingo.org/put")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Put JSON Array"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.putJsonArray("https://httpbingo.org/put")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Patch Body"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.patchBody("https://httpbingo.org/patch")
|
||||||
|
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Patch Form"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.patchForm("https://httpbingo.org/patch")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Patch JSON"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.patchJson("https://httpbingo.org/patch")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Patch JSON Array"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.patchJsonArray("https://httpbingo.org/patch")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Delete Body"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.deleteBody("https://httpbingo.org/delete")
|
||||||
|
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Delete Form"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.deleteForm("https://httpbingo.org/delete")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Delete JSON"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.deleteJson("https://httpbingo.org/delete")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Delete JSON Array"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.deleteJsonArray("https://httpbingo.org/delete")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Open Log"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.openLog(true)
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Custom Header"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.addHeader("os","PC")
|
||||||
|
.addHeader("version","1.0.0")
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "RequestFailedReadCache"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.setCacheMode(FluNetworkType.RequestFailedReadCache)
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.add("cacheMode","RequestFailedReadCache")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "IfNoneCacheRequest"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.setCacheMode(FluNetworkType.IfNoneCacheRequest)
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.add("cacheMode","IfNoneCacheRequest")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "FirstCacheThenRequest"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.setCacheMode(FluNetworkType.FirstCacheThenRequest)
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.add("cacheMode","FirstCacheThenRequest")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluButton{
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Timeout And Retry"
|
||||||
|
onClicked: {
|
||||||
|
text_info.text = ""
|
||||||
|
FluNetwork.postJson("https://httpbingo.org/post")
|
||||||
|
.setTimeout(5000)
|
||||||
|
.setRetry(3)
|
||||||
|
.add("name","孙悟空")
|
||||||
|
.add("age",500)
|
||||||
|
.add("address","花果山水帘洞")
|
||||||
|
.add("timeout","5000")
|
||||||
|
.add("retry","3")
|
||||||
|
.bind(root)
|
||||||
|
.go(callable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluProgressButton{
|
||||||
|
id:btn_upload
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Upload File"
|
||||||
|
onClicked: {
|
||||||
|
file_dialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluProgressButton{
|
||||||
|
id:btn_download
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Download File"
|
||||||
|
onClicked: {
|
||||||
|
folder_dialog.showDialog(function(path){
|
||||||
|
FluNetwork.get("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
|
||||||
|
.toDownload(path)
|
||||||
|
.bind(root)
|
||||||
|
.go(callable_download_file)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FluProgressButton{
|
||||||
|
id:btn_download_breakpoint
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: 36
|
||||||
|
text: "Breakpoint Download File"
|
||||||
|
onClicked: {
|
||||||
|
folder_dialog.showDialog(function(path){
|
||||||
|
FluNetwork.get("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
|
||||||
|
.toDownload(path,true)
|
||||||
|
.bind(root)
|
||||||
|
.go(callable_breakpoint_download_file)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluNetworkCallable{
|
||||||
|
id:callable_upload_file
|
||||||
|
onStart: {
|
||||||
|
btn_upload.disabled = true
|
||||||
|
}
|
||||||
|
onFinish: {
|
||||||
|
btn_upload.disabled = false
|
||||||
|
}
|
||||||
|
onError:
|
||||||
|
(status,errorString,result)=>{
|
||||||
|
btn_upload.progress = 0
|
||||||
|
text_info.text = result
|
||||||
|
console.debug(status+";"+errorString+";"+result)
|
||||||
|
}
|
||||||
|
onSuccess:
|
||||||
|
(result)=>{
|
||||||
|
text_info.text = result
|
||||||
|
}
|
||||||
|
onUploadProgress:
|
||||||
|
(sent,total)=>{
|
||||||
|
btn_upload.progress = sent/total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluNetworkCallable{
|
||||||
|
id:callable_download_file
|
||||||
|
onStart: {
|
||||||
|
btn_download.progress = 0
|
||||||
|
btn_download.disabled = true
|
||||||
|
}
|
||||||
|
onFinish: {
|
||||||
|
btn_download.disabled = false
|
||||||
|
}
|
||||||
|
onError:
|
||||||
|
(status,errorString,result)=>{
|
||||||
|
btn_download.progress = 0
|
||||||
|
showError(errorString)
|
||||||
|
console.debug(status+";"+errorString+";"+result)
|
||||||
|
}
|
||||||
|
onSuccess:
|
||||||
|
(result)=>{
|
||||||
|
showSuccess(result)
|
||||||
|
}
|
||||||
|
onDownloadProgress:
|
||||||
|
(recv,total)=>{
|
||||||
|
btn_download.progress = recv/total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluNetworkCallable{
|
||||||
|
id:callable_breakpoint_download_file
|
||||||
|
onStart: {
|
||||||
|
btn_download_breakpoint.progress = 0
|
||||||
|
btn_download_breakpoint.disabled = true
|
||||||
|
}
|
||||||
|
onFinish: {
|
||||||
|
btn_download_breakpoint.disabled = false
|
||||||
|
}
|
||||||
|
onError:
|
||||||
|
(status,errorString,result)=>{
|
||||||
|
btn_download_breakpoint.progress = 0
|
||||||
|
showError(errorString)
|
||||||
|
console.debug(status+";"+errorString+";"+result)
|
||||||
|
}
|
||||||
|
onSuccess:
|
||||||
|
(result)=>{
|
||||||
|
showSuccess(result)
|
||||||
|
}
|
||||||
|
onDownloadProgress:
|
||||||
|
(recv,total)=>{
|
||||||
|
btn_download_breakpoint.progress = recv/total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDialog {
|
||||||
|
id: file_dialog
|
||||||
|
onAccepted: {
|
||||||
|
FluNetwork.postForm("https://httpbingo.org/post")
|
||||||
|
.setRetry(1)//只请求一次
|
||||||
|
.add("accessToken","12345678")
|
||||||
|
.addFile("file",FluTools.toLocalPath(file_dialog.currentFile))
|
||||||
|
.bind(root)
|
||||||
|
.go(callable_upload_file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDialog {
|
||||||
|
property var onSelectListener
|
||||||
|
id: folder_dialog
|
||||||
|
folder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]
|
||||||
|
currentFile: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]+"/big_buck_bunny.mp4"
|
||||||
|
fileMode: FileDialog.SaveFile
|
||||||
|
onAccepted: {
|
||||||
|
folder_dialog.onSelectListener(FluTools.toLocalPath(folder_dialog.currentFile))
|
||||||
|
}
|
||||||
|
function showDialog(listener){
|
||||||
|
folder_dialog.onSelectListener = listener
|
||||||
|
folder_dialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
anchors{
|
||||||
|
top: layout_flick.top
|
||||||
|
bottom: layout_flick.bottom
|
||||||
|
left: layout_flick.right
|
||||||
|
right: parent.right
|
||||||
|
leftMargin: 8
|
||||||
|
}
|
||||||
|
Flickable{
|
||||||
|
clip: true
|
||||||
|
id:scrollview
|
||||||
|
boundsBehavior:Flickable.StopAtBounds
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
contentWidth: width
|
||||||
|
contentHeight: text_info.height
|
||||||
|
ScrollBar.vertical: FluScrollBar {}
|
||||||
|
FluText{
|
||||||
|
id:text_info
|
||||||
|
width: scrollview.width
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
padding: 14
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -32,6 +32,7 @@ FluScrollablePage{
|
|||||||
FluTextBox{
|
FluTextBox{
|
||||||
id:text_box
|
id:text_box
|
||||||
text:"会磨刀的小猪"
|
text:"会磨刀的小猪"
|
||||||
|
Layout.preferredWidth: 240
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ FluScrollablePage{
|
|||||||
color: FluTheme.dark ? FluColors.Black : FluColors.White
|
color: FluTheme.dark ? FluColors.Black : FluColors.White
|
||||||
FluShadow{
|
FluShadow{
|
||||||
radius: 4
|
radius: 4
|
||||||
color: FluTheme.primaryColor.dark
|
color: FluTheme.primaryColor
|
||||||
}
|
}
|
||||||
Image{
|
Image{
|
||||||
id:image
|
id:image
|
||||||
|
@ -65,16 +65,30 @@ FluScrollablePage{
|
|||||||
height: 50
|
height: 50
|
||||||
paddings: 10
|
paddings: 10
|
||||||
FluCheckBox{
|
FluCheckBox{
|
||||||
text:"V-Sync"
|
text:"Use System AppBar"
|
||||||
checked: FluApp.vsync
|
checked: FluApp.useSystemAppBar
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
onClicked: {
|
onClicked: {
|
||||||
FluApp.vsync = !FluApp.vsync
|
FluApp.useSystemAppBar = !FluApp.useSystemAppBar
|
||||||
dialog_restart.open()
|
dialog_restart.open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 20
|
||||||
|
height: 50
|
||||||
|
paddings: 10
|
||||||
|
FluCheckBox{
|
||||||
|
text:"fitsAppBarWindows"
|
||||||
|
checked: window.fitsAppBarWindows
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: {
|
||||||
|
window.fitsAppBarWindows = !window.fitsAppBarWindows
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FluArea{
|
FluArea{
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@ -202,5 +216,4 @@ FluScrollablePage{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
30
example/qml/page/T_ShortcutPicker.qml
Normal file
30
example/qml/page/T_ShortcutPicker.qml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import FluentUI 1.0
|
||||||
|
import "qrc:///example/qml/component"
|
||||||
|
|
||||||
|
FluScrollablePage{
|
||||||
|
|
||||||
|
title:"ShortcutPicker"
|
||||||
|
|
||||||
|
FluArea{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 20
|
||||||
|
height: 100
|
||||||
|
paddings: 10
|
||||||
|
FluShortcutPicker{
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CodeExpander{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: -1
|
||||||
|
code:'FluShortcutPicker{
|
||||||
|
|
||||||
|
}'
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -67,7 +67,7 @@ FluScrollablePage{
|
|||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color:FluTheme.primaryColor.dark
|
color:FluTheme.primaryColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ FluScrollablePage{
|
|||||||
statusMode: FluStatusViewType.Loading
|
statusMode: FluStatusViewType.Loading
|
||||||
Rectangle{
|
Rectangle{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color:FluTheme.primaryColor.dark
|
color:FluTheme.primaryColor
|
||||||
}
|
}
|
||||||
}'
|
}'
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ FluContentPage{
|
|||||||
iconSource: FluentIcons.ChevronUp
|
iconSource: FluentIcons.ChevronUp
|
||||||
iconColor: {
|
iconColor: {
|
||||||
if(1 === root.sortType){
|
if(1 === root.sortType){
|
||||||
return FluTheme.primaryColor.dark
|
return FluTheme.primaryColor
|
||||||
}
|
}
|
||||||
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
|
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
|
||||||
}
|
}
|
||||||
@ -203,7 +203,7 @@ FluContentPage{
|
|||||||
iconSource: FluentIcons.ChevronDown
|
iconSource: FluentIcons.ChevronDown
|
||||||
iconColor: {
|
iconColor: {
|
||||||
if(2 === root.sortType){
|
if(2 === root.sortType){
|
||||||
return FluTheme.primaryColor.dark
|
return FluTheme.primaryColor
|
||||||
}
|
}
|
||||||
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
|
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ FluScrollablePage{
|
|||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
iconSource: FluentIcons.AcceptMedium
|
iconSource: FluentIcons.AcceptMedium
|
||||||
iconSize: 15
|
iconSize: 15
|
||||||
visible: modelData === FluTheme.primaryColor
|
visible: modelData === FluTheme.themeColor
|
||||||
color: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
color: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||||
}
|
}
|
||||||
MouseArea{
|
MouseArea{
|
||||||
@ -41,7 +41,7 @@ FluScrollablePage{
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onClicked: {
|
onClicked: {
|
||||||
FluTheme.primaryColor = modelData
|
FluTheme.themeColor = modelData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ FluScrollablePage{
|
|||||||
CodeExpander{
|
CodeExpander{
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: -1
|
Layout.topMargin: -1
|
||||||
code:'FluTheme.primaryColor = FluColors.Orange
|
code:'FluTheme.themeColor = FluColors.Orange
|
||||||
|
|
||||||
FluTheme.dark = true
|
FluTheme.dark = true
|
||||||
|
|
||||||
|
@ -111,6 +111,7 @@ FluScrollablePage{
|
|||||||
FluTextBox{
|
FluTextBox{
|
||||||
id:text_box
|
id:text_box
|
||||||
text:"Technical testing 2015-09-01"
|
text:"Technical testing 2015-09-01"
|
||||||
|
Layout.preferredWidth: 240
|
||||||
}
|
}
|
||||||
FluFilledButton{
|
FluFilledButton{
|
||||||
text:"Append"
|
text:"Append"
|
||||||
|
@ -30,6 +30,7 @@ FluContentPage{
|
|||||||
FluTextBox{
|
FluTextBox{
|
||||||
id:text_box
|
id:text_box
|
||||||
text:"会磨刀的小猪"
|
text:"会磨刀的小猪"
|
||||||
|
Layout.preferredWidth: 240
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import FluentUI 1.0
|
|||||||
FluViewModel{
|
FluViewModel{
|
||||||
|
|
||||||
objectName: "SettingsViewModel"
|
objectName: "SettingsViewModel"
|
||||||
|
scope: FluViewModelType.Application
|
||||||
property int displayMode
|
property int displayMode
|
||||||
|
|
||||||
onInitData: {
|
onInitData: {
|
||||||
|
@ -61,11 +61,11 @@ FluWindow {
|
|||||||
event.accepted = false
|
event.accepted = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (event.urls.length !== 1) {
|
var url = getUrlByEvent(event)
|
||||||
|
if(url === ""){
|
||||||
event.accepted = false
|
event.accepted = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var url = event.urls[0].toString()
|
|
||||||
var fileExtension = url.substring(url.lastIndexOf(".") + 1)
|
var fileExtension = url.substring(url.lastIndexOf(".") + 1)
|
||||||
if (fileExtension !== "qml") {
|
if (fileExtension !== "qml") {
|
||||||
event.accepted = false
|
event.accepted = false
|
||||||
@ -75,12 +75,24 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
onDropped:
|
onDropped:
|
||||||
(event)=>{
|
(event)=>{
|
||||||
var path = event.urls[0].toString()
|
var url = getUrlByEvent(event)
|
||||||
loader.source = path
|
if(url !== ""){
|
||||||
watcher.path = path
|
loader.source = url
|
||||||
loader.reload()
|
watcher.path = url
|
||||||
|
loader.reload()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getUrlByEvent(event){
|
||||||
|
var url = ""
|
||||||
|
if (event.urls.length === 0) {
|
||||||
|
url = "file:///"+event.getDataAsString("text/plain")
|
||||||
|
}else{
|
||||||
|
url = event.urls[0].toString()
|
||||||
|
}
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,23 +16,25 @@ FluWindow {
|
|||||||
|
|
||||||
id:window
|
id:window
|
||||||
title: "FluentUI"
|
title: "FluentUI"
|
||||||
width: 1000
|
width: 960
|
||||||
height: 640
|
height: 600
|
||||||
closeDestory:false
|
|
||||||
minimumWidth: 520
|
minimumWidth: 520
|
||||||
minimumHeight: 200
|
minimumHeight: 200
|
||||||
launchMode: FluWindowType.SingleTask
|
launchMode: FluWindowType.SingleTask
|
||||||
appBar: undefined
|
fitsAppBarWindows: true
|
||||||
|
appBar: FluAppBar {
|
||||||
|
height: 30
|
||||||
|
darkText: Lang.dark_mode
|
||||||
|
showDark: true
|
||||||
|
darkClickListener:(button)=>handleDarkChanged(button)
|
||||||
|
closeClickListener: ()=>{dialog_close.open()}
|
||||||
|
z:7
|
||||||
|
}
|
||||||
|
|
||||||
SettingsViewModel{
|
SettingsViewModel{
|
||||||
id:viewmodel_settings
|
id:viewmodel_settings
|
||||||
}
|
}
|
||||||
|
|
||||||
closeListener:function(event){
|
|
||||||
dialog_close.open()
|
|
||||||
event.accepted = false
|
|
||||||
}
|
|
||||||
|
|
||||||
FluEvent{
|
FluEvent{
|
||||||
id:event_checkupdate
|
id:event_checkupdate
|
||||||
name: "checkUpdate"
|
name: "checkUpdate"
|
||||||
@ -41,9 +43,19 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onFirstVisible: {
|
||||||
|
timer_tour_delay.restart()
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer{
|
||||||
|
id:timer_tour_delay
|
||||||
|
interval: 200
|
||||||
|
onTriggered: {
|
||||||
|
tour.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
FluTools.setQuitOnLastWindowClosed(false)
|
|
||||||
tour.open()
|
|
||||||
checkUpdate(true)
|
checkUpdate(true)
|
||||||
FluEventBus.registerEvent(event_checkupdate)
|
FluEventBus.registerEvent(event_checkupdate)
|
||||||
}
|
}
|
||||||
@ -75,20 +87,43 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer{
|
||||||
|
id:timer_window_hide_delay
|
||||||
|
interval: 150
|
||||||
|
onTriggered: {
|
||||||
|
window.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FluContentDialog{
|
FluContentDialog{
|
||||||
id:dialog_close
|
id:dialog_close
|
||||||
title:"退出"
|
title:"退出"
|
||||||
message:"确定要退出程序吗?"
|
message:"确定要退出程序吗?"
|
||||||
negativeText:"最小化"
|
negativeText:"最小化"
|
||||||
buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.NeutralButton | FluContentDialogType.PositiveButton
|
buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.NeutralButton | FluContentDialogType.PositiveButton
|
||||||
onNegativeClicked:{
|
onNegativeClicked: {
|
||||||
window.hide()
|
|
||||||
system_tray.showMessage("友情提示","FluentUI已隐藏至托盘,点击托盘可再次激活窗口");
|
system_tray.showMessage("友情提示","FluentUI已隐藏至托盘,点击托盘可再次激活窗口");
|
||||||
|
timer_window_hide_delay.restart()
|
||||||
}
|
}
|
||||||
positiveText:"退出"
|
positiveText:"退出"
|
||||||
neutralText:"取消"
|
neutralText:"取消"
|
||||||
onPositiveClicked:{
|
onPositiveClicked:{
|
||||||
FluApp.exit()
|
FluApp.exit(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component{
|
||||||
|
id:nav_item_right_menu
|
||||||
|
FluMenu{
|
||||||
|
id:menu
|
||||||
|
width: 130
|
||||||
|
FluMenuItem{
|
||||||
|
text: "在独立窗口打开"
|
||||||
|
visible: true
|
||||||
|
onClicked: {
|
||||||
|
FluApp.navigate("/pageWindow",{title:modelData.title,url:modelData.url})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,18 +150,8 @@ FluWindow {
|
|||||||
back: Item{
|
back: Item{
|
||||||
anchors.fill: flipable
|
anchors.fill: flipable
|
||||||
visible: flipable.flipAngle !== 0
|
visible: flipable.flipAngle !== 0
|
||||||
FluAppBar {
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
darkText: Lang.dark_mode
|
|
||||||
showDark: true
|
|
||||||
z:7
|
|
||||||
darkClickListener:(button)=>handleDarkChanged(button)
|
|
||||||
}
|
|
||||||
Row{
|
Row{
|
||||||
|
id:layout_back_buttons
|
||||||
z:8
|
z:8
|
||||||
anchors{
|
anchors{
|
||||||
top: parent.top
|
top: parent.top
|
||||||
@ -157,25 +182,13 @@ FluWindow {
|
|||||||
id:loader
|
id:loader
|
||||||
lazy: true
|
lazy: true
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: "https://zhu-zichu.gitee.io/Qt5_156_LieflatPage.qml"
|
source: "https://zhu-zichu.gitee.io/Qt_163_LieflatPage.qml"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
front: Item{
|
front: Item{
|
||||||
id:page_front
|
id:page_front
|
||||||
visible: flipable.flipAngle !== 180
|
visible: flipable.flipAngle !== 180
|
||||||
anchors.fill: flipable
|
anchors.fill: flipable
|
||||||
FluAppBar {
|
|
||||||
id:app_bar_front
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
darkText: Lang.dark_mode
|
|
||||||
showDark: true
|
|
||||||
darkClickListener:(button)=>handleDarkChanged(button)
|
|
||||||
z:7
|
|
||||||
}
|
|
||||||
FluNavigationView{
|
FluNavigationView{
|
||||||
property int clickCount: 0
|
property int clickCount: 0
|
||||||
id:nav_view
|
id:nav_view
|
||||||
@ -188,7 +201,12 @@ FluWindow {
|
|||||||
pageMode: FluNavigationViewType.NoStack
|
pageMode: FluNavigationViewType.NoStack
|
||||||
items: ItemsOriginal
|
items: ItemsOriginal
|
||||||
footerItems:ItemsFooter
|
footerItems:ItemsFooter
|
||||||
topPadding:FluTools.isMacos() ? 20 : 0
|
topPadding:{
|
||||||
|
if(window.useSystemAppBar){
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return FluTools.isMacos() ? 20 : 0
|
||||||
|
}
|
||||||
displayMode:viewmodel_settings.displayMode
|
displayMode:viewmodel_settings.displayMode
|
||||||
logo: "qrc:/example/res/image/favicon.ico"
|
logo: "qrc:/example/res/image/favicon.ico"
|
||||||
title:"FluentUI"
|
title:"FluentUI"
|
||||||
@ -212,7 +230,9 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
ItemsOriginal.navigationView = nav_view
|
ItemsOriginal.navigationView = nav_view
|
||||||
|
ItemsOriginal.paneItemMenu = nav_item_right_menu
|
||||||
ItemsFooter.navigationView = nav_view
|
ItemsFooter.navigationView = nav_view
|
||||||
|
ItemsFooter.paneItemMenu = nav_item_right_menu
|
||||||
setCurrentIndex(0)
|
setCurrentIndex(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,7 +243,7 @@ FluWindow {
|
|||||||
id:com_reveal
|
id:com_reveal
|
||||||
CircularReveal{
|
CircularReveal{
|
||||||
id:reveal
|
id:reveal
|
||||||
target:window.contentItem
|
target:window.layoutContainer()
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onAnimationFinished:{
|
onAnimationFinished:{
|
||||||
//动画结束后释放资源
|
//动画结束后释放资源
|
||||||
@ -235,7 +255,7 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader{
|
FluLoader{
|
||||||
id:loader_reveal
|
id:loader_reveal
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
@ -245,11 +265,14 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleDarkChanged(button){
|
function handleDarkChanged(button){
|
||||||
if(FluTools.isMacos() || !FluTheme.enableAnimation){
|
if(!FluTheme.enableAnimation || window.fitsAppBarWindows === false){
|
||||||
changeDark()
|
changeDark()
|
||||||
}else{
|
}else{
|
||||||
|
if(loader_reveal.sourceComponent){
|
||||||
|
return
|
||||||
|
}
|
||||||
loader_reveal.sourceComponent = com_reveal
|
loader_reveal.sourceComponent = com_reveal
|
||||||
var target = window.contentItem
|
var target = window.layoutContainer()
|
||||||
var pos = button.mapToItem(target,0,0)
|
var pos = button.mapToItem(target,0,0)
|
||||||
var mouseX = pos.x
|
var mouseX = pos.x
|
||||||
var mouseY = pos.y
|
var mouseY = pos.y
|
||||||
@ -287,14 +310,14 @@ FluWindow {
|
|||||||
|
|
||||||
FluTour{
|
FluTour{
|
||||||
id:tour
|
id:tour
|
||||||
steps:[
|
steps:{
|
||||||
{title:"夜间模式",description: "这里可以切换夜间模式.",target:()=>app_bar_front.darkButton()},
|
var data = []
|
||||||
{title:"隐藏彩蛋",description: "多点几下试试!!",target:()=>nav_view.logoButton()}
|
if(!window.useSystemAppBar){
|
||||||
]
|
data.push({title:"夜间模式",description: "这里可以切换夜间模式.",target:()=>appBar.darkButton()})
|
||||||
}
|
}
|
||||||
|
data.push({title:"隐藏彩蛋",description: "多点几下试试!!",target:()=>nav_view.logoButton()})
|
||||||
FluHttp{
|
return data
|
||||||
id:http
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FpsItem{
|
FpsItem{
|
||||||
@ -326,7 +349,7 @@ FluWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpCallable{
|
FluNetworkCallable{
|
||||||
id:callable
|
id:callable
|
||||||
property bool silent: true
|
property bool silent: true
|
||||||
onStart: {
|
onStart: {
|
||||||
@ -362,8 +385,8 @@ FluWindow {
|
|||||||
|
|
||||||
function checkUpdate(silent){
|
function checkUpdate(silent){
|
||||||
callable.silent = silent
|
callable.silent = silent
|
||||||
var request = http.newRequest("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest")
|
FluNetwork.get("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest")
|
||||||
http.get(request,callable);
|
.go(callable)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ FluWindow {
|
|||||||
window.title = arg.title
|
window.title = arg.title
|
||||||
loader.setSource( arg.url,{animDisabled:true})
|
loader.setSource( arg.url,{animDisabled:true})
|
||||||
}
|
}
|
||||||
Loader{
|
FluLoader{
|
||||||
id: loader
|
id: loader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,11 @@
|
|||||||
|
|
||||||
CircularReveal::CircularReveal(QQuickItem* parent) : QQuickPaintedItem(parent)
|
CircularReveal::CircularReveal(QQuickItem* parent) : QQuickPaintedItem(parent)
|
||||||
{
|
{
|
||||||
|
_anim = new QPropertyAnimation(this, "radius", this);
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
_anim.setDuration(333);
|
_anim->setDuration(333);
|
||||||
_anim.setEasingCurve(QEasingCurve::OutCubic);
|
_anim->setEasingCurve(QEasingCurve::OutCubic);
|
||||||
connect(&_anim, &QPropertyAnimation::finished,this,[=](){
|
connect(_anim, &QPropertyAnimation::finished,this,[=](){
|
||||||
update();
|
update();
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
Q_EMIT animationFinished();
|
Q_EMIT animationFinished();
|
||||||
@ -31,8 +32,8 @@ void CircularReveal::paint(QPainter* painter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CircularReveal::start(int w,int h,const QPoint& center,int radius){
|
void CircularReveal::start(int w,int h,const QPoint& center,int radius){
|
||||||
_anim.setStartValue(0);
|
_anim->setStartValue(0);
|
||||||
_anim.setEndValue(radius);
|
_anim->setEndValue(radius);
|
||||||
_center = center;
|
_center = center;
|
||||||
_grabResult = _target->grabToImage(QSize(w,h));
|
_grabResult = _target->grabToImage(QSize(w,h));
|
||||||
connect(_grabResult.data(), &QQuickItemGrabResult::ready, this, &CircularReveal::handleGrabResult);
|
connect(_grabResult.data(), &QQuickItemGrabResult::ready, this, &CircularReveal::handleGrabResult);
|
||||||
@ -43,5 +44,5 @@ void CircularReveal::handleGrabResult(){
|
|||||||
update();
|
update();
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
Q_EMIT imageChanged();
|
Q_EMIT imageChanged();
|
||||||
_anim.start();
|
_anim->start();
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ public:
|
|||||||
Q_SIGNAL void animationFinished();
|
Q_SIGNAL void animationFinished();
|
||||||
Q_SLOT void handleGrabResult();
|
Q_SLOT void handleGrabResult();
|
||||||
private:
|
private:
|
||||||
|
QPropertyAnimation* _anim = nullptr;
|
||||||
QImage _source;
|
QImage _source;
|
||||||
QPropertyAnimation _anim = QPropertyAnimation(this, "radius", this);
|
|
||||||
QPoint _center;
|
QPoint _center;
|
||||||
QSharedPointer<QQuickItemGrabResult> _grabResult;
|
QSharedPointer<QQuickItemGrabResult> _grabResult;
|
||||||
};
|
};
|
||||||
|
204
example/src/helper/Log.cpp
Normal file
204
example/src/helper/Log.cpp
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
#include "Log.h"
|
||||||
|
#include <QtCore/qdebug.h>
|
||||||
|
#include <QtCore/qfile.h>
|
||||||
|
#include <QtCore/qtextstream.h>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <iostream>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include "Version.h"
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <process.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef QT_ENDL
|
||||||
|
# if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||||
|
# define QT_ENDL Qt::endl
|
||||||
|
# else
|
||||||
|
# define QT_ENDL endl
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static QString g_app = {};
|
||||||
|
static QString g_file_path= {};
|
||||||
|
static bool g_logError = false;
|
||||||
|
|
||||||
|
static std::unique_ptr<QFile> g_logFile = nullptr;
|
||||||
|
static std::unique_ptr<QTextStream> g_logStream = nullptr;
|
||||||
|
|
||||||
|
static int g_logLevel = 4;
|
||||||
|
|
||||||
|
std::map<QtMsgType, int> logLevelMap = {
|
||||||
|
{QtFatalMsg,0},
|
||||||
|
{QtCriticalMsg,1},
|
||||||
|
{QtWarningMsg,2},
|
||||||
|
{QtInfoMsg,3},
|
||||||
|
{QtDebugMsg,4}
|
||||||
|
};
|
||||||
|
|
||||||
|
QString Log::prettyProductInfoWrapper()
|
||||||
|
{
|
||||||
|
auto productName = QSysInfo::prettyProductName();
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
|
||||||
|
#if defined(Q_OS_MACOS)
|
||||||
|
auto macosVersionFile = QString::fromUtf8("/System/Library/CoreServices/.SystemVersionPlatform.plist");
|
||||||
|
auto fi = QFileInfo (macosVersionFile);
|
||||||
|
if (fi.exists() && fi.isReadable()) {
|
||||||
|
auto plistFile = QFile(macosVersionFile);
|
||||||
|
plistFile.open(QIODevice::ReadOnly);
|
||||||
|
while (!plistFile.atEnd()) {
|
||||||
|
auto line = plistFile.readLine();
|
||||||
|
if (line.contains("ProductUserVisibleVersion")) {
|
||||||
|
auto nextLine = plistFile.readLine();
|
||||||
|
if (nextLine.contains("<string>")) {
|
||||||
|
QRegularExpression re(QString::fromUtf8("\\s*<string>(.*)</string>"));
|
||||||
|
auto matches = re.match(QString::fromUtf8(nextLine));
|
||||||
|
if (matches.hasMatch()) {
|
||||||
|
productName = QString::fromUtf8("macOS ") + matches.captured(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
QSettings regKey {QString::fromUtf8("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), QSettings::NativeFormat};
|
||||||
|
if (regKey.contains(QString::fromUtf8("CurrentBuildNumber"))) {
|
||||||
|
auto buildNumber = regKey.value(QString::fromUtf8("CurrentBuildNumber")).toInt();
|
||||||
|
if (buildNumber > 0) {
|
||||||
|
if (buildNumber < 9200) {
|
||||||
|
productName = QString::fromUtf8("Windows 7 build %1").arg(buildNumber);
|
||||||
|
}
|
||||||
|
else if (buildNumber < 10240) {
|
||||||
|
productName = QString::fromUtf8("Windows 8 build %1").arg(buildNumber);
|
||||||
|
}
|
||||||
|
else if (buildNumber < 22000) {
|
||||||
|
productName = QString::fromUtf8("Windows 10 build %1").arg(buildNumber);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
productName = QString::fromUtf8("Windows 11 build %1").arg(buildNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return productName;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void myMessageHandler(const QtMsgType type, const QMessageLogContext &context, const QString &message)
|
||||||
|
{
|
||||||
|
if(logLevelMap[type]>g_logLevel){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!message.isEmpty()) {
|
||||||
|
QString levelName;
|
||||||
|
switch (type) {
|
||||||
|
case QtDebugMsg:
|
||||||
|
levelName = QStringLiteral("Debug");
|
||||||
|
break;
|
||||||
|
case QtInfoMsg:
|
||||||
|
levelName = QStringLiteral("Info");
|
||||||
|
break;
|
||||||
|
case QtWarningMsg:
|
||||||
|
levelName = QStringLiteral("Warning");
|
||||||
|
break;
|
||||||
|
case QtCriticalMsg:
|
||||||
|
levelName = QStringLiteral("Critical");
|
||||||
|
break;
|
||||||
|
case QtFatalMsg:
|
||||||
|
levelName = QStringLiteral("Fatal");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QString fileAndLineLogStr;
|
||||||
|
if(context.file){
|
||||||
|
std::string strFileTmp = context.file;
|
||||||
|
const char* ptr = strrchr(strFileTmp.c_str(), '/');
|
||||||
|
if (nullptr != ptr) {
|
||||||
|
char fn[512] = {0};
|
||||||
|
sprintf(fn, "%s", ptr + 1);
|
||||||
|
strFileTmp = fn;
|
||||||
|
}
|
||||||
|
const char* ptrTmp = strrchr(strFileTmp.c_str(), '\\');
|
||||||
|
if (nullptr != ptrTmp) {
|
||||||
|
char fn[512] = {0};
|
||||||
|
sprintf(fn, "%s", ptrTmp + 1);
|
||||||
|
strFileTmp = fn;
|
||||||
|
}
|
||||||
|
fileAndLineLogStr = QString::fromStdString("[%1:%2]").arg(QString::fromStdString(strFileTmp),QString::number(context.line));
|
||||||
|
}
|
||||||
|
const QString finalMessage = QString::fromStdString("%1[%2]%3[%4]:%5").arg(
|
||||||
|
QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss.zzz"),
|
||||||
|
levelName,
|
||||||
|
fileAndLineLogStr,
|
||||||
|
QString::number(reinterpret_cast<quintptr>(QThread::currentThreadId())),
|
||||||
|
message);
|
||||||
|
if ((type == QtInfoMsg) || (type == QtDebugMsg)) {
|
||||||
|
std::cout << qPrintable(finalMessage) << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cerr << qPrintable(finalMessage) << std::endl;
|
||||||
|
}
|
||||||
|
if (g_logError) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!g_logFile) {
|
||||||
|
g_logFile = std::make_unique<QFile>(g_file_path);
|
||||||
|
if (!g_logFile->open(QFile::WriteOnly | QFile::Text | QFile::Append)) {
|
||||||
|
std::cerr << "Can't open file to write: " << qPrintable(g_logFile->errorString()) << std::endl;
|
||||||
|
g_logFile.reset();
|
||||||
|
g_logError = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!g_logStream) {
|
||||||
|
g_logStream = std::make_unique<QTextStream>();
|
||||||
|
g_logStream->setDevice(g_logFile.get());
|
||||||
|
}
|
||||||
|
(*g_logStream) << finalMessage << QT_ENDL;
|
||||||
|
g_logStream->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::setup(const QString &app)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!app.isEmpty());
|
||||||
|
if (app.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
static bool once = false;
|
||||||
|
if (once) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
once = true;
|
||||||
|
g_app = app;
|
||||||
|
const QString logFileName = QString("%1_%2.log").arg(g_app,QDateTime::currentDateTime().toString("yyyyMMdd"));
|
||||||
|
const QString logDirPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)+"/log";
|
||||||
|
const QDir logDir(logDirPath);
|
||||||
|
if(!logDir.exists()){
|
||||||
|
logDir.mkpath(logDirPath);
|
||||||
|
}
|
||||||
|
g_file_path = logDir.filePath(logFileName);
|
||||||
|
qInstallMessageHandler(myMessageHandler);
|
||||||
|
qInfo()<<"===================================================";
|
||||||
|
qInfo()<<"[AppName]"<<g_app;
|
||||||
|
qInfo()<<"[AppVersion]"<<APPLICATION_VERSION;
|
||||||
|
#ifdef WIN32
|
||||||
|
qInfo()<<"[ProcessId]"<<QString::number(_getpid());
|
||||||
|
#else
|
||||||
|
qInfo()<<"[ProcessId]"<<QString::number(getpid());
|
||||||
|
#endif
|
||||||
|
qInfo()<<"[GitHashCode]"<<COMMIT_HASH;
|
||||||
|
qInfo()<<"[DeviceInfo]";
|
||||||
|
qInfo()<<" [DeviceId]"<<QSysInfo::machineUniqueId();
|
||||||
|
qInfo()<<" [Manufacturer]"<<prettyProductInfoWrapper();
|
||||||
|
qInfo()<<" [CPU_ABI]"<<QSysInfo::currentCpuArchitecture();
|
||||||
|
qInfo()<<"[LOG_LEVEL]"<<g_logLevel;
|
||||||
|
qInfo()<<"[LOG_PATH]"<<g_file_path;
|
||||||
|
qInfo()<<"===================================================";
|
||||||
|
}
|
11
example/src/helper/Log.h
Normal file
11
example/src/helper/Log.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef LOG_H
|
||||||
|
#define LOG_H
|
||||||
|
#include <QtCore/qstring.h>
|
||||||
|
|
||||||
|
namespace Log
|
||||||
|
{
|
||||||
|
QString prettyProductInfoWrapper();
|
||||||
|
void setup(const QString &app);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // LOG_H
|
@ -12,23 +12,15 @@ SettingsHelper::~SettingsHelper() = default;
|
|||||||
|
|
||||||
void SettingsHelper::save(const QString& key,QVariant val)
|
void SettingsHelper::save(const QString& key,QVariant val)
|
||||||
{
|
{
|
||||||
QByteArray data = {};
|
m_settings->setValue(key, val);
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
|
||||||
stream.setVersion(QDataStream::Qt_5_6);
|
|
||||||
stream << val;
|
|
||||||
m_settings->setValue(key, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant SettingsHelper::get(const QString& key){
|
QVariant SettingsHelper::get(const QString& key,QVariant def){
|
||||||
const QByteArray data = m_settings->value(key).toByteArray();
|
QVariant data = m_settings->value(key);
|
||||||
if (data.isEmpty()) {
|
if (!data.isNull() && data.isValid()) {
|
||||||
return {};
|
return data;
|
||||||
}
|
}
|
||||||
QDataStream stream(data);
|
return def;
|
||||||
stream.setVersion(QDataStream::Qt_5_6);
|
|
||||||
QVariant val;
|
|
||||||
stream >> val;
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsHelper::init(char *argv[]){
|
void SettingsHelper::init(char *argv[]){
|
||||||
@ -36,6 +28,5 @@ void SettingsHelper::init(char *argv[]){
|
|||||||
const QFileInfo fileInfo(applicationPath);
|
const QFileInfo fileInfo(applicationPath);
|
||||||
const QString iniFileName = fileInfo.completeBaseName() + ".ini";
|
const QString iniFileName = fileInfo.completeBaseName() + ".ini";
|
||||||
const QString iniFilePath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/" + iniFileName;
|
const QString iniFilePath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/" + iniFileName;
|
||||||
qDebug()<<"Application configuration file path->"<<iniFilePath;
|
|
||||||
m_settings.reset(new QSettings(iniFilePath, QSettings::IniFormat));
|
m_settings.reset(new QSettings(iniFilePath, QSettings::IniFormat));
|
||||||
}
|
}
|
||||||
|
@ -19,15 +19,15 @@ public:
|
|||||||
SINGLETONG(SettingsHelper)
|
SINGLETONG(SettingsHelper)
|
||||||
~SettingsHelper() override;
|
~SettingsHelper() override;
|
||||||
void init(char *argv[]);
|
void init(char *argv[]);
|
||||||
Q_INVOKABLE void saveRender(const QString& render){save("render",render);}
|
Q_INVOKABLE void saveRender(const QVariant& render){save("render",render);}
|
||||||
Q_INVOKABLE QString getRender(){return get("render").toString();}
|
Q_INVOKABLE QString getRender(){return get("render").toString();}
|
||||||
Q_INVOKABLE void saveDarkMode(int darkModel){save("darkMode",darkModel);}
|
Q_INVOKABLE void saveDarkMode(int darkModel){save("darkMode",darkModel);}
|
||||||
Q_INVOKABLE int getDarkMode(){return get("darkMode").toInt(0);}
|
Q_INVOKABLE int getDarkMode(){return get("darkMode",QVariant(0)).toInt();}
|
||||||
Q_INVOKABLE void saveVsync(bool vsync){save("vsync",vsync);}
|
Q_INVOKABLE void saveUseSystemAppBar(bool useSystemAppBar){save("useSystemAppBar",useSystemAppBar);}
|
||||||
Q_INVOKABLE bool getVsync(){return get("vsync").toBool();}
|
Q_INVOKABLE bool getUseSystemAppBar(){return get("useSystemAppBar",QVariant(false)).toBool();}
|
||||||
private:
|
private:
|
||||||
void save(const QString& key,QVariant val);
|
void save(const QString& key,QVariant val);
|
||||||
QVariant get(const QString& key);
|
QVariant get(const QString& key,QVariant def={});
|
||||||
private:
|
private:
|
||||||
QScopedPointer<QSettings> m_settings;
|
QScopedPointer<QSettings> m_settings;
|
||||||
};
|
};
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <QtQml/qqmlextensionplugin.h>
|
#include <QtQml/qqmlextensionplugin.h>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
#include "AppInfo.h"
|
#include "AppInfo.h"
|
||||||
|
#include "helper/Log.h"
|
||||||
#include "src/component/CircularReveal.h"
|
#include "src/component/CircularReveal.h"
|
||||||
#include "src/component/FileWatcher.h"
|
#include "src/component/FileWatcher.h"
|
||||||
#include "src/component/FpsItem.h"
|
#include "src/component/FpsItem.h"
|
||||||
@ -23,7 +24,18 @@ Q_IMPORT_QML_PLUGIN(FluentUIPlugin)
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
|
qputenv("QT_QUICK_CONTROLS_STYLE","Basic");
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
//fix bug UOSv20 does not print logs
|
||||||
|
qputenv("QT_LOGGING_RULES","");
|
||||||
|
//fix bug UOSv20 v-sync does not work
|
||||||
|
qputenv("QSG_RENDER_LOOP","basic");
|
||||||
|
#endif
|
||||||
|
QGuiApplication::setOrganizationName("ZhuZiChu");
|
||||||
|
QGuiApplication::setOrganizationDomain("https://zhuzichu520.github.io");
|
||||||
|
QGuiApplication::setApplicationName("FluentUI");
|
||||||
|
SettingsHelper::getInstance()->init(argv);
|
||||||
|
Log::setup("example");
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
@ -31,11 +43,6 @@ int main(int argc, char *argv[])
|
|||||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
qputenv("QT_QUICK_CONTROLS_STYLE","Basic");
|
|
||||||
QGuiApplication::setOrganizationName("ZhuZiChu");
|
|
||||||
QGuiApplication::setOrganizationDomain("https://zhuzichu520.github.io");
|
|
||||||
QGuiApplication::setApplicationName("FluentUI");
|
|
||||||
SettingsHelper::getInstance()->init(argv);
|
|
||||||
if(SettingsHelper::getInstance()->getRender()=="software"){
|
if(SettingsHelper::getInstance()->getRender()=="software"){
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||||
QQuickWindow::setGraphicsApi(QSGRendererInterface::Software);
|
QQuickWindow::setGraphicsApi(QSGRendererInterface::Software);
|
||||||
@ -53,7 +60,6 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef FLUENTUI_BUILD_STATIC_LIB
|
#ifdef FLUENTUI_BUILD_STATIC_LIB
|
||||||
FluentUI::getInstance()->registerTypes(&engine);
|
FluentUI::getInstance()->registerTypes(&engine);
|
||||||
#endif
|
#endif
|
||||||
qDebug()<<engine.importPathList();
|
|
||||||
qmlRegisterType<CircularReveal>("example", 1, 0, "CircularReveal");
|
qmlRegisterType<CircularReveal>("example", 1, 0, "CircularReveal");
|
||||||
qmlRegisterType<FileWatcher>("example", 1, 0, "FileWatcher");
|
qmlRegisterType<FileWatcher>("example", 1, 0, "FileWatcher");
|
||||||
qmlRegisterType<FpsItem>("example", 1, 0, "FpsItem");
|
qmlRegisterType<FpsItem>("example", 1, 0, "FpsItem");
|
||||||
|
Submodule framelesshelper deleted from 295fb74e69
@ -1,16 +1,14 @@
|
|||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
|
||||||
if (FLUENTUI_BUILD_STATIC_LIB AND (QT_VERSION VERSION_GREATER_EQUAL "6.2"))
|
if (FLUENTUI_BUILD_STATIC_LIB AND (QT_VERSION VERSION_GREATER_EQUAL "6.2"))
|
||||||
project(fluentui LANGUAGES CXX)
|
project(fluentui VERSION 1.0)
|
||||||
else()
|
else()
|
||||||
project(fluentuiplugin LANGUAGES CXX)
|
project(fluentuiplugin VERSION 1.0)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#配置通用编译
|
#配置通用编译
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
if(APPLE)
|
|
||||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (FLUENTUI_BUILD_STATIC_LIB)
|
if (FLUENTUI_BUILD_STATIC_LIB)
|
||||||
add_definitions(-DFLUENTUI_BUILD_STATIC_LIB)
|
add_definitions(-DFLUENTUI_BUILD_STATIC_LIB)
|
||||||
@ -120,11 +118,14 @@ else()
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_compile_definitions(${PROJECT_NAME}
|
||||||
|
PRIVATE
|
||||||
|
HAVE_CONFIG_H
|
||||||
|
)
|
||||||
|
|
||||||
#去掉mingw生成的动态库libxxx前缀lib,不去掉前缀会导致 module "FluentUI" plugin "fluentuiplugin" not found
|
#去掉mingw生成的动态库libxxx前缀lib,不去掉前缀会导致 module "FluentUI" plugin "fluentuiplugin" not found
|
||||||
if(MINGW)
|
if(MINGW)
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
|
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX ".debug")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#MSVC Debug 添加后缀d,与Qt插件风格保持一致
|
#MSVC Debug 添加后缀d,与Qt插件风格保持一致
|
||||||
@ -137,9 +138,6 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
|
|||||||
Qt${QT_VERSION_MAJOR}::CorePrivate
|
Qt${QT_VERSION_MAJOR}::CorePrivate
|
||||||
Qt${QT_VERSION_MAJOR}::QuickPrivate
|
Qt${QT_VERSION_MAJOR}::QuickPrivate
|
||||||
Qt${QT_VERSION_MAJOR}::QmlPrivate
|
Qt${QT_VERSION_MAJOR}::QmlPrivate
|
||||||
ZXing
|
|
||||||
FramelessHelper::Core
|
|
||||||
FramelessHelper::Quick
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#安装
|
#安装
|
||||||
|
@ -14,7 +14,7 @@ Q_ENUM_NS(Scope)
|
|||||||
QML_NAMED_ELEMENT(FluViewModelType)
|
QML_NAMED_ELEMENT(FluViewModelType)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace FluHttpType {
|
namespace FluNetworkType {
|
||||||
Q_NAMESPACE
|
Q_NAMESPACE
|
||||||
enum CacheMode {
|
enum CacheMode {
|
||||||
NoCache = 0x0000,
|
NoCache = 0x0000,
|
||||||
@ -23,7 +23,7 @@ enum CacheMode {
|
|||||||
FirstCacheThenRequest = 0x0004,
|
FirstCacheThenRequest = 0x0004,
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(CacheMode)
|
Q_ENUM_NS(CacheMode)
|
||||||
QML_NAMED_ELEMENT(FluHttpType)
|
QML_NAMED_ELEMENT(FluNetworkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace FluScreenshotType {
|
namespace FluScreenshotType {
|
||||||
|
@ -8,34 +8,21 @@
|
|||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <FramelessHelper/Quick/framelessquickmodule.h>
|
|
||||||
#include <FramelessHelper/Core/private/framelessconfig_p.h>
|
|
||||||
|
|
||||||
FRAMELESSHELPER_USE_NAMESPACE
|
|
||||||
|
|
||||||
FluApp::FluApp(QObject *parent):QObject{parent}{
|
FluApp::FluApp(QObject *parent):QObject{parent}{
|
||||||
vsync(false);
|
vsync(true);
|
||||||
httpInterceptor(nullptr);
|
useSystemAppBar(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
FluApp::~FluApp(){
|
FluApp::~FluApp(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void FluApp::init(QQuickWindow *window){
|
void FluApp::init(QObject *application){
|
||||||
this->_application = window;
|
this->_application = application;
|
||||||
FramelessHelper::Quick::initialize();
|
QJSEngine * jsEngine = qjsEngine(_application);
|
||||||
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
|
std::string jsFunction = R"( (function () { console.log("FluentUI");}) )";
|
||||||
FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow);
|
QJSValue function = jsEngine->evaluate(QString::fromStdString(jsFunction));
|
||||||
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur);
|
jsEngine->globalObject().setProperty("__fluentui",function);
|
||||||
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow,false);
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_MACOS
|
|
||||||
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur,false);
|
|
||||||
#endif
|
|
||||||
QQmlEngine *engine = qmlEngine(_application);
|
|
||||||
FramelessHelper::Quick::registerTypes(engine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FluApp::run(){
|
void FluApp::run(){
|
||||||
@ -88,6 +75,7 @@ void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegist
|
|||||||
|
|
||||||
void FluApp::exit(int retCode){
|
void FluApp::exit(int retCode){
|
||||||
for (const auto& pair : _windows.toStdMap()) {
|
for (const auto& pair : _windows.toStdMap()) {
|
||||||
|
pair.second->close();
|
||||||
removeWindow(pair.second);
|
removeWindow(pair.second);
|
||||||
}
|
}
|
||||||
qApp->exit(retCode);
|
qApp->exit(retCode);
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
#include "FluRegister.h"
|
#include "FluRegister.h"
|
||||||
#include "FluHttpInterceptor.h"
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "singleton.h"
|
#include "singleton.h"
|
||||||
|
|
||||||
@ -22,7 +21,8 @@ class FluApp : public QObject
|
|||||||
Q_PROPERTY_AUTO(bool,vsync)
|
Q_PROPERTY_AUTO(bool,vsync)
|
||||||
Q_PROPERTY_AUTO(QString,initialRoute);
|
Q_PROPERTY_AUTO(QString,initialRoute);
|
||||||
Q_PROPERTY_AUTO(QJsonObject,routes);
|
Q_PROPERTY_AUTO(QJsonObject,routes);
|
||||||
Q_PROPERTY_AUTO(FluHttpInterceptor*,httpInterceptor);
|
Q_PROPERTY_AUTO(bool,useSystemAppBar);
|
||||||
|
Q_PROPERTY_AUTO(QString,windowIcon);
|
||||||
QML_NAMED_ELEMENT(FluApp)
|
QML_NAMED_ELEMENT(FluApp)
|
||||||
QML_SINGLETON
|
QML_SINGLETON
|
||||||
private:
|
private:
|
||||||
@ -33,13 +33,13 @@ public:
|
|||||||
static FluApp *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
|
static FluApp *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
|
||||||
Q_INVOKABLE void run();
|
Q_INVOKABLE void run();
|
||||||
Q_INVOKABLE void navigate(const QString& route,const QJsonObject& argument = {},FluRegister* fluRegister = nullptr);
|
Q_INVOKABLE void navigate(const QString& route,const QJsonObject& argument = {},FluRegister* fluRegister = nullptr);
|
||||||
Q_INVOKABLE void init(QQuickWindow *window);
|
Q_INVOKABLE void init(QObject *window);
|
||||||
Q_INVOKABLE void exit(int retCode = 0);
|
Q_INVOKABLE void exit(int retCode = 0);
|
||||||
void addWindow(QQuickWindow* window);
|
void addWindow(QQuickWindow* window);
|
||||||
void removeWindow(QQuickWindow* window);
|
void removeWindow(QQuickWindow* window);
|
||||||
private:
|
private:
|
||||||
QMap<quint64, QQuickWindow*> _windows;
|
QMap<quint64, QQuickWindow*> _windows;
|
||||||
QWindow* _application;
|
QObject* _application;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FLUAPP_H
|
#endif // FLUAPP_H
|
||||||
|
256
src/FluFramelessHelper.cpp
Normal file
256
src/FluFramelessHelper.cpp
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
#include "FluFramelessHelper.h"
|
||||||
|
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QOperatingSystemVersion>
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#pragma comment (lib,"user32.lib")
|
||||||
|
#pragma comment (lib,"dwmapi.lib")
|
||||||
|
#include <windows.h>
|
||||||
|
#include <dwmapi.h>
|
||||||
|
|
||||||
|
static inline QByteArray qtNativeEventType()
|
||||||
|
{
|
||||||
|
static const auto result = "windows_generic_MSG";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
static inline bool isCompositionEnabled(){
|
||||||
|
typedef HRESULT (WINAPI* DwmIsCompositionEnabledPtr)(BOOL *pfEnabled);
|
||||||
|
HMODULE module = LoadLibraryW(L"dwmapi.dll");
|
||||||
|
if (module)
|
||||||
|
{
|
||||||
|
BOOL composition_enabled = false;
|
||||||
|
DwmIsCompositionEnabledPtr dwm_is_composition_enabled;
|
||||||
|
dwm_is_composition_enabled= reinterpret_cast<DwmIsCompositionEnabledPtr>(GetProcAddress(module, "DwmIsCompositionEnabled"));
|
||||||
|
if (dwm_is_composition_enabled)
|
||||||
|
{
|
||||||
|
dwm_is_composition_enabled(&composition_enabled);
|
||||||
|
}
|
||||||
|
return composition_enabled;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void showShadow(HWND hwnd){
|
||||||
|
if(isCompositionEnabled()){
|
||||||
|
const MARGINS shadow = { 1, 1, 1, 1 };
|
||||||
|
typedef HRESULT (WINAPI* DwmExtendFrameIntoClientAreaPtr)(HWND hWnd, const MARGINS *pMarInset);
|
||||||
|
HMODULE module = LoadLibraryW(L"dwmapi.dll");
|
||||||
|
if (module)
|
||||||
|
{
|
||||||
|
DwmExtendFrameIntoClientAreaPtr dwm_extendframe_into_client_area_;
|
||||||
|
dwm_extendframe_into_client_area_= reinterpret_cast<DwmExtendFrameIntoClientAreaPtr>(GetProcAddress(module, "DwmExtendFrameIntoClientArea"));
|
||||||
|
if (dwm_extendframe_into_client_area_)
|
||||||
|
{
|
||||||
|
dwm_extendframe_into_client_area_(hwnd, &shadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
ULONG_PTR cNewStyle = GetClassLongPtr(hwnd, GCL_STYLE) | CS_DROPSHADOW;
|
||||||
|
SetClassLongPtr(hwnd, GCL_STYLE, cNewStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FramelessEventFilter::FramelessEventFilter(QQuickWindow* window){
|
||||||
|
_window = window;
|
||||||
|
_current = window->winId();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FramelessEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result){
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
if ((eventType != qtNativeEventType()) || !message || !result || !_window) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto msg = static_cast<const MSG *>(message);
|
||||||
|
const HWND hwnd = msg->hwnd;
|
||||||
|
if (!hwnd) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const qint64 wid = reinterpret_cast<qint64>(hwnd);
|
||||||
|
if(wid != _current){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const UINT uMsg = msg->message;
|
||||||
|
const WPARAM wParam = msg->wParam;
|
||||||
|
const LPARAM lParam = msg->lParam;
|
||||||
|
if (!msg || !hwnd)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(uMsg == WM_WINDOWPOSCHANGING){
|
||||||
|
WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(lParam);
|
||||||
|
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0)
|
||||||
|
{
|
||||||
|
wp->flags |= SWP_NOCOPYBITS;
|
||||||
|
*result = DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}else if(uMsg == WM_NCCALCSIZE){
|
||||||
|
*result = WVR_REDRAW;
|
||||||
|
return true;
|
||||||
|
}else if(uMsg == WM_NCPAINT){
|
||||||
|
if(!isCompositionEnabled()){
|
||||||
|
*result = WVR_REDRAW;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}else if(uMsg == WM_NCACTIVATE){
|
||||||
|
if(!isCompositionEnabled()){
|
||||||
|
*result = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FluFramelessHelper::FluFramelessHelper(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluFramelessHelper::classBegin(){
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluFramelessHelper::updateCursor(int edges){
|
||||||
|
switch (edges) {
|
||||||
|
case 0:
|
||||||
|
_window->setCursor(Qt::ArrowCursor);
|
||||||
|
break;
|
||||||
|
case Qt::LeftEdge:
|
||||||
|
case Qt::RightEdge:
|
||||||
|
_window->setCursor(Qt::SizeHorCursor);
|
||||||
|
break;
|
||||||
|
case Qt::TopEdge:
|
||||||
|
case Qt::BottomEdge:
|
||||||
|
_window->setCursor(Qt::SizeVerCursor);
|
||||||
|
break;
|
||||||
|
case Qt::LeftEdge | Qt::TopEdge:
|
||||||
|
case Qt::RightEdge | Qt::BottomEdge:
|
||||||
|
_window->setCursor(Qt::SizeFDiagCursor);
|
||||||
|
break;
|
||||||
|
case Qt::RightEdge | Qt::TopEdge:
|
||||||
|
case Qt::LeftEdge | Qt::BottomEdge:
|
||||||
|
_window->setCursor(Qt::SizeBDiagCursor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FluFramelessHelper::eventFilter(QObject *obj, QEvent *ev){
|
||||||
|
if (!_window.isNull() && _window->flags() & Qt::FramelessWindowHint) {
|
||||||
|
|
||||||
|
static int edges = 0;
|
||||||
|
const int margin = 8;
|
||||||
|
switch (ev->type()) {
|
||||||
|
case QEvent::MouseButtonPress:
|
||||||
|
if(edges!=0){
|
||||||
|
updateCursor(edges);
|
||||||
|
_window->startSystemResize(Qt::Edges(edges));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QEvent::MouseButtonRelease:
|
||||||
|
edges = 0;
|
||||||
|
updateCursor(edges);
|
||||||
|
break;
|
||||||
|
case QEvent::MouseMove: {
|
||||||
|
if(_window->visibility() == QWindow::Maximized || _window->visibility() == QWindow::FullScreen){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(_window->width() == _window->maximumWidth() && _window->width() == _window->minimumWidth() && _window->height() == _window->maximumHeight() && _window->height() == _window->minimumHeight()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
||||||
|
QPoint p =
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||||
|
event->pos();
|
||||||
|
#else
|
||||||
|
event->position().toPoint();
|
||||||
|
#endif
|
||||||
|
if(p.x() >= margin && p.x() <= (_window->width() - margin) && p.y() >= margin && p.y() <= (_window->height() - margin)){
|
||||||
|
if(edges != 0){
|
||||||
|
edges = 0;
|
||||||
|
updateCursor(edges);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
edges = 0;
|
||||||
|
if ( p.x() < margin ) {
|
||||||
|
edges |= Qt::LeftEdge;
|
||||||
|
}
|
||||||
|
if ( p.x() > (_window->width() - margin) ) {
|
||||||
|
edges |= Qt::RightEdge;
|
||||||
|
}
|
||||||
|
if ( p.y() < margin ) {
|
||||||
|
edges |= Qt::TopEdge;
|
||||||
|
}
|
||||||
|
if ( p.y() > (_window->height() - margin) ) {
|
||||||
|
edges |= Qt::BottomEdge;
|
||||||
|
}
|
||||||
|
updateCursor(edges);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QObject::eventFilter(obj, ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluFramelessHelper::componentComplete(){
|
||||||
|
auto o = parent();
|
||||||
|
while (nullptr != o) {
|
||||||
|
_window = (QQuickWindow*)o;
|
||||||
|
o = o->parent();
|
||||||
|
}
|
||||||
|
if(!_window.isNull()){
|
||||||
|
_window->setFlags(Qt::FramelessWindowHint|Qt::Window|Qt::WindowTitleHint|Qt::WindowMinMaxButtonsHint|Qt::WindowCloseButtonHint);
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
_nativeEvent =new FramelessEventFilter(_window);
|
||||||
|
qApp->installNativeEventFilter(_nativeEvent);
|
||||||
|
HWND hwnd = reinterpret_cast<HWND>(_window->winId());
|
||||||
|
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE |SWP_FRAMECHANGED);
|
||||||
|
showShadow(hwnd);
|
||||||
|
#endif
|
||||||
|
_stayTop = QQmlProperty(_window,"stayTop");
|
||||||
|
_onStayTopChange();
|
||||||
|
_stayTop.connectNotifySignal(this,SLOT(_onStayTopChange()));
|
||||||
|
_screen = QQmlProperty(_window,"screen");
|
||||||
|
_screen.connectNotifySignal(this,SLOT(_onScreenChanged()));
|
||||||
|
_window->installEventFilter(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluFramelessHelper::_onScreenChanged(){
|
||||||
|
_window->update();
|
||||||
|
QGuiApplication::processEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluFramelessHelper::_onStayTopChange(){
|
||||||
|
bool isStayTop = _stayTop.read().toBool();
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
HWND hwnd = reinterpret_cast<HWND>(_window->winId());
|
||||||
|
DWORD style = GetWindowLongPtr(hwnd,GWL_STYLE);
|
||||||
|
SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_CAPTION &~ WS_SYSMENU);
|
||||||
|
if(isStayTop){
|
||||||
|
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||||
|
}else{
|
||||||
|
SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
_window->setFlag(Qt::WindowStaysOnTopHint,isStayTop);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
FluFramelessHelper::~FluFramelessHelper(){
|
||||||
|
if (!_window.isNull()) {
|
||||||
|
_window->setFlags(Qt::Window);
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
qApp->removeNativeEventFilter(_nativeEvent);
|
||||||
|
#endif
|
||||||
|
_window->removeEventFilter(this);
|
||||||
|
}
|
||||||
|
}
|
50
src/FluFramelessHelper.h
Normal file
50
src/FluFramelessHelper.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#ifndef FLUFRAMELESSHELPER_H
|
||||||
|
#define FLUFRAMELESSHELPER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQuickWindow>
|
||||||
|
#include <QtQml/qqml.h>
|
||||||
|
#include <QAbstractNativeEventFilter>
|
||||||
|
#include <QQmlProperty>
|
||||||
|
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||||
|
using QT_NATIVE_EVENT_RESULT_TYPE = qintptr;
|
||||||
|
using QT_ENTER_EVENT_TYPE = QEnterEvent;
|
||||||
|
#else
|
||||||
|
using QT_NATIVE_EVENT_RESULT_TYPE = long;
|
||||||
|
using QT_ENTER_EVENT_TYPE = QEvent;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class FramelessEventFilter : public QAbstractNativeEventFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FramelessEventFilter(QQuickWindow* window);
|
||||||
|
bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) override;
|
||||||
|
public:
|
||||||
|
QQuickWindow* _window = nullptr;
|
||||||
|
qint64 _current = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FluFramelessHelper : public QObject, public QQmlParserStatus
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
QML_NAMED_ELEMENT(FluFramelessHelper)
|
||||||
|
public:
|
||||||
|
explicit FluFramelessHelper(QObject *parent = nullptr);
|
||||||
|
~FluFramelessHelper();
|
||||||
|
void classBegin() override;
|
||||||
|
void componentComplete() override;
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
|
private:
|
||||||
|
void updateCursor(int edges);
|
||||||
|
Q_SLOT void _onStayTopChange();
|
||||||
|
Q_SLOT void _onScreenChanged();
|
||||||
|
private:
|
||||||
|
QPointer<QQuickWindow> _window = nullptr;
|
||||||
|
FramelessEventFilter* _nativeEvent = nullptr;
|
||||||
|
QQmlProperty _stayTop;
|
||||||
|
QQmlProperty _screen;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FLUFRAMELESSHELPER_H
|
681
src/FluHttp.cpp
681
src/FluHttp.cpp
@ -1,681 +0,0 @@
|
|||||||
#include "FluHttp.h"
|
|
||||||
|
|
||||||
#include <QThreadPool>
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QUrlQuery>
|
|
||||||
#include <QHttpMultiPart>
|
|
||||||
#include <QGuiApplication>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QStandardPaths>
|
|
||||||
#include <QTextStream>
|
|
||||||
#include <QDir>
|
|
||||||
#include "Def.h"
|
|
||||||
#include "FluApp.h"
|
|
||||||
#include "FluTools.h"
|
|
||||||
|
|
||||||
HttpRequest::HttpRequest(QObject *parent):QObject{parent}{
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, QVariant> HttpRequest::toMap(){
|
|
||||||
QVariant _params;
|
|
||||||
bool isPostString = method() == "postString";
|
|
||||||
if(params().isNull()){
|
|
||||||
if(isPostString){
|
|
||||||
_params = "";
|
|
||||||
}else{
|
|
||||||
_params = QMap<QString,QVariant>();
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
_params = params();
|
|
||||||
}
|
|
||||||
QVariant _headers;
|
|
||||||
if(headers().isNull()){
|
|
||||||
_headers = QMap<QString,QVariant>();
|
|
||||||
}else{
|
|
||||||
_headers = headers();
|
|
||||||
}
|
|
||||||
QMap<QString, QVariant> request = {
|
|
||||||
{"url",url()},
|
|
||||||
{"headers",_headers.toMap()},
|
|
||||||
{"method",method()},
|
|
||||||
{"downloadSavePath",downloadSavePath()}
|
|
||||||
};
|
|
||||||
if(isPostString){
|
|
||||||
request.insert("params",_params.toString());
|
|
||||||
}else{
|
|
||||||
request.insert("params",_params.toMap());
|
|
||||||
}
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString HttpRequest::httpId(){
|
|
||||||
return FluTools::getInstance()->sha256(QJsonDocument::fromVariant(QVariant(toMap())).toJson(QJsonDocument::Compact));
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpCallable::HttpCallable(QObject *parent):QObject{parent}{
|
|
||||||
}
|
|
||||||
|
|
||||||
FluHttp::FluHttp(QObject *parent):QObject{parent}{
|
|
||||||
retry(3);
|
|
||||||
timeout(15000);
|
|
||||||
cacheMode(FluHttpType::CacheMode::NoCache);
|
|
||||||
cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/httpcache");
|
|
||||||
breakPointDownload(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
FluHttp::~FluHttp(){
|
|
||||||
cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::cancel(){
|
|
||||||
foreach (QPointer<QNetworkReply> item, _cacheReply) {
|
|
||||||
if(item){
|
|
||||||
item->abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::post(HttpRequest* r,HttpCallable* c){
|
|
||||||
auto request = QPointer(r);
|
|
||||||
auto callable = QPointer(c);
|
|
||||||
request->method("post");
|
|
||||||
auto requestMap = request->toMap();
|
|
||||||
auto httpId = request->httpId();
|
|
||||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
|
||||||
QThreadPool::globalInstance()->start([=](){
|
|
||||||
onStart(callable);
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
onFinish(callable,request);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
}
|
|
||||||
QNetworkAccessManager manager;
|
|
||||||
manager.setTransferTimeout(timeout());
|
|
||||||
for (int i = 0; i < retry(); ++i) {
|
|
||||||
QUrl url(request->url());
|
|
||||||
QNetworkRequest req(url);
|
|
||||||
addHeaders(&req,data["headers"].toMap());
|
|
||||||
QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
|
|
||||||
for (const auto& each : data["params"].toMap().toStdMap())
|
|
||||||
{
|
|
||||||
const QString& key = each.first;
|
|
||||||
const QString& value = each.second.toString();
|
|
||||||
QString dispositionHeader = QString("form-data; name=\"%1\"").arg(key);
|
|
||||||
QHttpPart part;
|
|
||||||
part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
|
|
||||||
part.setBody(value.toUtf8());
|
|
||||||
multiPart.append(part);
|
|
||||||
}
|
|
||||||
QNetworkReply* reply = manager.post(req,&multiPart);
|
|
||||||
if(!QPointer(qApp)){
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_cacheReply.append(reply);
|
|
||||||
QEventLoop loop;
|
|
||||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
|
||||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
|
||||||
loop.exec();
|
|
||||||
QString result = QString::fromUtf8(reply->readAll());
|
|
||||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
||||||
QString errorString = reply->errorString();
|
|
||||||
QNetworkReply::NetworkError error = reply->error();
|
|
||||||
bool isSuccess = error == QNetworkReply::NoError;
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
if (isSuccess) {
|
|
||||||
handleCache(httpId,result);
|
|
||||||
onSuccess(callable,result);
|
|
||||||
break;
|
|
||||||
}else{
|
|
||||||
if(i == retry()-1){
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
}
|
|
||||||
onError(callable,status,errorString,result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(error == QNetworkReply::OperationCanceledError){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onFinish(callable,request);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::postString(HttpRequest* r,HttpCallable* c){
|
|
||||||
auto request = QPointer(r);
|
|
||||||
auto callable = QPointer(c);
|
|
||||||
request->method("postString");
|
|
||||||
auto requestMap = request->toMap();
|
|
||||||
auto httpId = request->httpId();
|
|
||||||
QString params = request->params().toString();
|
|
||||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
|
||||||
QThreadPool::globalInstance()->start([=](){
|
|
||||||
onStart(callable);
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
onFinish(callable,request);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
}
|
|
||||||
QNetworkAccessManager manager;
|
|
||||||
manager.setTransferTimeout(timeout());
|
|
||||||
for (int i = 0; i < retry(); ++i) {
|
|
||||||
QUrl url(request->url());
|
|
||||||
QNetworkRequest req(url);
|
|
||||||
addHeaders(&req,data["headers"].toMap());
|
|
||||||
QString contentType = QString("text/plain;charset=utf-8");
|
|
||||||
req.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
|
|
||||||
QNetworkReply* reply = manager.post(req,params.toUtf8());
|
|
||||||
if(!QPointer(qApp)){
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_cacheReply.append(reply);
|
|
||||||
QEventLoop loop;
|
|
||||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
|
||||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
|
||||||
loop.exec();
|
|
||||||
QString result = QString::fromUtf8(reply->readAll());
|
|
||||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
||||||
QString errorString = reply->errorString();
|
|
||||||
QNetworkReply::NetworkError error = reply->error();
|
|
||||||
bool isSuccess = error == QNetworkReply::NoError;
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
if (isSuccess) {
|
|
||||||
handleCache(httpId,result);
|
|
||||||
onSuccess(callable,result);
|
|
||||||
break;
|
|
||||||
}else{
|
|
||||||
if(i == retry()-1){
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
}
|
|
||||||
onError(callable,status,errorString,result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(error == QNetworkReply::OperationCanceledError){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onFinish(callable,request);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::postJson(HttpRequest* r,HttpCallable* c){
|
|
||||||
auto request = QPointer(r);
|
|
||||||
auto callable = QPointer(c);
|
|
||||||
request->method("postJson");
|
|
||||||
auto requestMap = request->toMap();
|
|
||||||
auto httpId = request->httpId();
|
|
||||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
|
||||||
QThreadPool::globalInstance()->start([=](){
|
|
||||||
onStart(callable);
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
onFinish(callable,request);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
}
|
|
||||||
QNetworkAccessManager manager;
|
|
||||||
manager.setTransferTimeout(timeout());
|
|
||||||
for (int i = 0; i < retry(); ++i) {
|
|
||||||
QUrl url(request->url());
|
|
||||||
QNetworkRequest req(url);
|
|
||||||
addHeaders(&req,data["headers"].toMap());
|
|
||||||
QString contentType = QString("application/json;charset=utf-8");
|
|
||||||
req.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
|
|
||||||
QNetworkReply* reply = manager.post(req,QJsonDocument::fromVariant(data["params"]).toJson());
|
|
||||||
if(!QPointer(qApp)){
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_cacheReply.append(reply);
|
|
||||||
QEventLoop loop;
|
|
||||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
|
||||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
|
||||||
loop.exec();
|
|
||||||
QString result = QString::fromUtf8(reply->readAll());
|
|
||||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
||||||
QString errorString = reply->errorString();
|
|
||||||
QNetworkReply::NetworkError error = reply->error();
|
|
||||||
bool isSuccess = error == QNetworkReply::NoError;
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
if (isSuccess) {
|
|
||||||
handleCache(httpId,result);
|
|
||||||
onSuccess(callable,result);
|
|
||||||
break;
|
|
||||||
}else{
|
|
||||||
if(i == retry()-1){
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
}
|
|
||||||
onError(callable,status,errorString,result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(error == QNetworkReply::OperationCanceledError){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onFinish(callable,request);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::get(HttpRequest* r,HttpCallable* c){
|
|
||||||
auto request = QPointer(r);
|
|
||||||
auto callable = QPointer(c);
|
|
||||||
request->method("get");
|
|
||||||
auto requestMap = request->toMap();
|
|
||||||
auto httpId = request->httpId();
|
|
||||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
|
||||||
QThreadPool::globalInstance()->start([=](){
|
|
||||||
onStart(callable);
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
}
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
onFinish(callable,request);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QNetworkAccessManager manager;
|
|
||||||
manager.setTransferTimeout(timeout());
|
|
||||||
for (int i = 0; i < retry(); ++i) {
|
|
||||||
QUrl url(request->url());
|
|
||||||
addQueryParam(&url,data["params"].toMap());
|
|
||||||
QNetworkRequest req(url);
|
|
||||||
addHeaders(&req,data["headers"].toMap());
|
|
||||||
QNetworkReply* reply = manager.get(req);
|
|
||||||
if(!QPointer(qApp)){
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_cacheReply.append(reply);
|
|
||||||
QEventLoop loop;
|
|
||||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
|
||||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
|
||||||
loop.exec();
|
|
||||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
||||||
QString errorString = reply->errorString();
|
|
||||||
QNetworkReply::NetworkError error = reply->error();
|
|
||||||
bool isSuccess = error == QNetworkReply::NoError;
|
|
||||||
QString result = QString::fromUtf8(reply->readAll());
|
|
||||||
if (isSuccess) {
|
|
||||||
handleCache(httpId,result);
|
|
||||||
onSuccess(callable,result);
|
|
||||||
break;
|
|
||||||
}else{
|
|
||||||
if(i == retry()-1){
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
}
|
|
||||||
onError(callable,status,errorString,result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
if(error == QNetworkReply::OperationCanceledError){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onFinish(callable,request);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::download(HttpRequest* r,HttpCallable* c){
|
|
||||||
auto request = QPointer(r);
|
|
||||||
auto callable = QPointer(c);
|
|
||||||
request->method("download");
|
|
||||||
auto requestMap = request->toMap();
|
|
||||||
auto httpId = request->httpId();
|
|
||||||
auto savePath = request->downloadSavePath();
|
|
||||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
|
||||||
QThreadPool::globalInstance()->start([=](){
|
|
||||||
onStart(callable);
|
|
||||||
QNetworkAccessManager manager;
|
|
||||||
QUrl url(request->url());
|
|
||||||
addQueryParam(&url,data["params"].toMap());
|
|
||||||
QNetworkRequest req(url);
|
|
||||||
addHeaders(&req,data["headers"].toMap());
|
|
||||||
QSharedPointer<QFile> file(new QFile(savePath));
|
|
||||||
QDir dir = QFileInfo(savePath).path();
|
|
||||||
if (!dir.exists(dir.path())){
|
|
||||||
dir.mkpath(dir.path());
|
|
||||||
}
|
|
||||||
qint64 seek = 0;
|
|
||||||
auto filePath = getCacheFilePath(httpId);
|
|
||||||
QSharedPointer<QFile> fileCache(new QFile(filePath));
|
|
||||||
if(fileCache->exists() && file->exists() && _breakPointDownload){
|
|
||||||
QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(httpId).toUtf8()).object();
|
|
||||||
qint64 fileSize = cacheInfo.value("fileSize").toDouble();
|
|
||||||
qint64 contentLength = cacheInfo.value("contentLength").toDouble();
|
|
||||||
if(fileSize == contentLength && file->size() == contentLength){
|
|
||||||
onDownloadProgress(callable,fileSize,contentLength);
|
|
||||||
onSuccess(callable,savePath);
|
|
||||||
onFinish(callable,request);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(fileSize==file->size()){
|
|
||||||
req.setRawHeader("Range", QString("bytes=%1-").arg(fileSize).toUtf8());
|
|
||||||
seek = fileSize;
|
|
||||||
file->open(QIODevice::WriteOnly|QIODevice::Append);
|
|
||||||
}else{
|
|
||||||
file->open(QIODevice::WriteOnly|QIODevice::Truncate);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
file->open(QIODevice::WriteOnly|QIODevice::Truncate);
|
|
||||||
}
|
|
||||||
QNetworkReply* reply = manager.get(req);
|
|
||||||
if(!QPointer(qApp)){
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_cacheReply.append(reply);
|
|
||||||
QEventLoop loop;
|
|
||||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
|
||||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
|
||||||
if (!fileCache->open(QIODevice::WriteOnly|QIODevice::Truncate))
|
|
||||||
{
|
|
||||||
qDebug()<<"FileCache Error";
|
|
||||||
}
|
|
||||||
connect(reply,&QNetworkReply::readyRead,reply,[reply,file,fileCache,requestMap,callable,seek,this]{
|
|
||||||
if (!reply || !file || reply->error() != QNetworkReply::NoError)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QMap<QString, QVariant> downMap = requestMap;
|
|
||||||
qint64 contentLength = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong()+seek;
|
|
||||||
downMap.insert("contentLength",contentLength);
|
|
||||||
QString eTag = reply->header(QNetworkRequest::ETagHeader).toString();
|
|
||||||
downMap.insert("eTag",eTag);
|
|
||||||
file->write(reply->readAll());
|
|
||||||
file->flush();
|
|
||||||
downMap.insert("fileSize",file->size());
|
|
||||||
fileCache->resize(0);
|
|
||||||
fileCache->write(FluTools::getInstance()->toBase64(QJsonDocument::fromVariant(QVariant(downMap)).toJson()).toUtf8());
|
|
||||||
fileCache->flush();
|
|
||||||
onDownloadProgress(callable,file->size(),contentLength);
|
|
||||||
});
|
|
||||||
loop.exec();
|
|
||||||
if (reply->error() == QNetworkReply::NoError) {
|
|
||||||
onSuccess(callable,savePath);
|
|
||||||
}else{
|
|
||||||
onError(callable,reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString(),"");
|
|
||||||
}
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
onFinish(callable,request);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::upload(HttpRequest* request,HttpCallable* callable){
|
|
||||||
request->method("upload");
|
|
||||||
auto requestMap = request->toMap();
|
|
||||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
|
||||||
QThreadPool::globalInstance()->start([=](){
|
|
||||||
onStart(callable);
|
|
||||||
QNetworkAccessManager manager;
|
|
||||||
manager.setTransferTimeout(timeout());
|
|
||||||
QUrl url(request->url());
|
|
||||||
QNetworkRequest req(url);
|
|
||||||
addHeaders(&req,data["headers"].toMap());
|
|
||||||
QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
|
|
||||||
for (const auto& each : data["params"].toMap().toStdMap())
|
|
||||||
{
|
|
||||||
const QString& key = each.first;
|
|
||||||
const QString& filePath = each.second.toString();
|
|
||||||
QFile *file = new QFile(filePath);
|
|
||||||
file->open(QIODevice::ReadOnly);
|
|
||||||
file->setParent(&multiPart);
|
|
||||||
QString dispositionHeader = QString("form-data; name=\"%1\"; filename=\"%2\"").arg(key,filePath);
|
|
||||||
QHttpPart part;
|
|
||||||
part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
|
|
||||||
part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
|
|
||||||
part.setBodyDevice(file);
|
|
||||||
multiPart.append(part);
|
|
||||||
}
|
|
||||||
QNetworkReply* reply = manager.post(req,&multiPart);
|
|
||||||
if(!QPointer(qApp)){
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_cacheReply.append(reply);
|
|
||||||
QEventLoop loop;
|
|
||||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
|
||||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
|
||||||
connect(reply,&QNetworkReply::uploadProgress,reply,[=](qint64 bytesSent, qint64 bytesTotal){
|
|
||||||
onUploadProgress(callable,bytesSent,bytesTotal);
|
|
||||||
});
|
|
||||||
loop.exec();
|
|
||||||
QString result = QString::fromUtf8(reply->readAll());
|
|
||||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
||||||
QString errorString = reply->errorString();
|
|
||||||
bool isSuccess = reply->error() == QNetworkReply::NoError;
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
if (isSuccess) {
|
|
||||||
onSuccess(callable,result);
|
|
||||||
}else{
|
|
||||||
onError(callable,status,errorString,result);
|
|
||||||
}
|
|
||||||
onFinish(callable,request);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::deleteResource(HttpRequest* request,HttpCallable* callable)
|
|
||||||
{
|
|
||||||
request->method("deleteResource");
|
|
||||||
auto requestMap = request->toMap();
|
|
||||||
auto httpId = request->httpId();
|
|
||||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
|
||||||
QThreadPool::globalInstance()->start([=](){
|
|
||||||
onStart(callable);
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
}
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
onFinish(callable,request);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QNetworkAccessManager manager;
|
|
||||||
manager.setTransferTimeout(timeout());
|
|
||||||
for (int i = 0; i < retry(); ++i) {
|
|
||||||
QUrl url(request->url());
|
|
||||||
addQueryParam(&url,data["params"].toMap());
|
|
||||||
QNetworkRequest req(url);
|
|
||||||
addHeaders(&req,data["headers"].toMap());
|
|
||||||
QEventLoop loop;
|
|
||||||
QNetworkReply* reply = manager.deleteResource(req);
|
|
||||||
_cacheReply.append(reply);
|
|
||||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
|
||||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop](){loop.quit();});
|
|
||||||
loop.exec();
|
|
||||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
||||||
QString errorString = reply->errorString();
|
|
||||||
bool isSuccess = reply->error() == QNetworkReply::NoError;
|
|
||||||
QString result = QString::fromUtf8(reply->readAll());
|
|
||||||
if (isSuccess) {
|
|
||||||
handleCache(httpId,result);
|
|
||||||
onSuccess(callable,result);
|
|
||||||
break;
|
|
||||||
}else{
|
|
||||||
if(i == retry()-1){
|
|
||||||
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
|
|
||||||
onCache(callable,readCache(httpId));
|
|
||||||
}
|
|
||||||
onError(callable,status,errorString,result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QNetworkReply::NetworkError error = reply->error();
|
|
||||||
if(error == QNetworkReply::OperationCanceledError){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
}
|
|
||||||
onFinish(callable,request);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant FluHttp::invokeIntercept(QMap<QString, QVariant> request){
|
|
||||||
if(!FluApp::getInstance()->httpInterceptor()){
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
QVariant target;
|
|
||||||
QMetaObject::invokeMethod(FluApp::getInstance()->httpInterceptor(), "onIntercept",Q_RETURN_ARG(QVariant,target),Q_ARG(QVariant, request));
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::addQueryParam(QUrl* url,const QMap<QString, QVariant>& params){
|
|
||||||
QMapIterator<QString, QVariant> iter(params);
|
|
||||||
QUrlQuery urlQuery(*url);
|
|
||||||
while (iter.hasNext())
|
|
||||||
{
|
|
||||||
iter.next();
|
|
||||||
urlQuery.addQueryItem(iter.key(), iter.value().toString());
|
|
||||||
}
|
|
||||||
url->setQuery(urlQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers){
|
|
||||||
QMapIterator<QString, QVariant> iter(headers);
|
|
||||||
while (iter.hasNext())
|
|
||||||
{
|
|
||||||
iter.next();
|
|
||||||
request->setRawHeader(iter.key().toUtf8(), iter.value().toString().toUtf8());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString FluHttp::readCache(const QString& httpId){
|
|
||||||
auto filePath = getCacheFilePath(httpId);
|
|
||||||
QString result;
|
|
||||||
QFile file(filePath);
|
|
||||||
if(!file.exists()){
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (file.open(QIODevice::ReadOnly)) {
|
|
||||||
QTextStream stream(&file);
|
|
||||||
result = FluTools::getInstance()->fromBase64(stream.readAll().toUtf8());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FluHttp::cacheExists(const QString& httpId){
|
|
||||||
return QFile(getCacheFilePath(httpId)).exists();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString FluHttp::getCacheFilePath(const QString& httpId){
|
|
||||||
QString path = FluTools::getInstance()->toLocalPath(QUrl(_cacheDir));
|
|
||||||
QDir dir = path;
|
|
||||||
if (!dir.exists(path)){
|
|
||||||
dir.mkpath(path);
|
|
||||||
}
|
|
||||||
auto filePath = path+"/"+httpId;
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::handleCache(const QString& httpId,const QString& result){
|
|
||||||
if(_cacheMode==FluHttpType::CacheMode::NoCache){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto filePath = getCacheFilePath(httpId);
|
|
||||||
QSharedPointer<QFile> file(new QFile(filePath));
|
|
||||||
QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate;
|
|
||||||
if (!file->open(mode))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
file->write(FluTools::getInstance()->toBase64(result).toUtf8());
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal FluHttp::getBreakPointProgress(HttpRequest* request){
|
|
||||||
request->method("download");
|
|
||||||
auto httpId = request->httpId();
|
|
||||||
QSharedPointer<QFile> file(new QFile(request->downloadSavePath()));
|
|
||||||
auto filePath = getCacheFilePath(httpId);
|
|
||||||
QSharedPointer<QFile> fileCache(new QFile(filePath));
|
|
||||||
if(fileCache->exists() && file->exists() && _breakPointDownload){
|
|
||||||
QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(httpId).toUtf8()).object();
|
|
||||||
double fileSize = cacheInfo.value("fileSize").toDouble();
|
|
||||||
double contentLength = cacheInfo.value("contentLength").toDouble();
|
|
||||||
if(fileSize == contentLength && file->size() == contentLength){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if(fileSize==file->size()){
|
|
||||||
return fileSize/contentLength;
|
|
||||||
}else{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpRequest* FluHttp::newRequest(QString url){
|
|
||||||
HttpRequest* request = new HttpRequest(this);
|
|
||||||
request->url(url);
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::onStart(QPointer<HttpCallable> callable){
|
|
||||||
if(callable){
|
|
||||||
Q_EMIT callable->start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::onFinish(QPointer<HttpCallable> callable,QPointer<HttpRequest> request){
|
|
||||||
if(callable){
|
|
||||||
Q_EMIT callable->finish();
|
|
||||||
}
|
|
||||||
if(request&&request->parent()->inherits("FluHttp")){
|
|
||||||
request->deleteLater();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::onError(QPointer<HttpCallable> callable,int status,QString errorString,QString result){
|
|
||||||
if(callable){
|
|
||||||
Q_EMIT callable->error(status,errorString,result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::onSuccess(QPointer<HttpCallable> callable,QString result){
|
|
||||||
if(callable){
|
|
||||||
Q_EMIT callable->success(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::onCache(QPointer<HttpCallable> callable,QString result){
|
|
||||||
if(callable){
|
|
||||||
Q_EMIT callable->cache(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::onDownloadProgress(QPointer<HttpCallable> callable,qint64 recv,qint64 total){
|
|
||||||
if(callable){
|
|
||||||
Q_EMIT callable->downloadProgress(recv,total);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FluHttp::onUploadProgress(QPointer<HttpCallable> callable,qint64 sent,qint64 total){
|
|
||||||
if(callable){
|
|
||||||
Q_EMIT callable->uploadProgress(sent,total);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
#ifndef FLUHTTP_H
|
|
||||||
#define FLUHTTP_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QtQml/qqml.h>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
class HttpRequest : public QObject{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY_AUTO(QString,url);
|
|
||||||
Q_PROPERTY_AUTO(QVariant,params);
|
|
||||||
Q_PROPERTY_AUTO(QVariant,headers);
|
|
||||||
Q_PROPERTY_AUTO(QString,method);
|
|
||||||
Q_PROPERTY_AUTO(QString,downloadSavePath);
|
|
||||||
QML_NAMED_ELEMENT(HttpRequest)
|
|
||||||
public:
|
|
||||||
explicit HttpRequest(QObject *parent = nullptr);
|
|
||||||
QMap<QString, QVariant> toMap();
|
|
||||||
Q_INVOKABLE QString httpId();
|
|
||||||
};
|
|
||||||
|
|
||||||
class HttpCallable : public QObject{
|
|
||||||
Q_OBJECT
|
|
||||||
QML_NAMED_ELEMENT(HttpCallable)
|
|
||||||
public:
|
|
||||||
explicit HttpCallable(QObject *parent = nullptr);
|
|
||||||
Q_SIGNAL void start();
|
|
||||||
Q_SIGNAL void finish();
|
|
||||||
Q_SIGNAL void error(int status,QString errorString,QString result);
|
|
||||||
Q_SIGNAL void success(QString result);
|
|
||||||
Q_SIGNAL void cache(QString result);
|
|
||||||
Q_SIGNAL void downloadProgress(qint64 recv, qint64 total);
|
|
||||||
Q_SIGNAL void uploadProgress(qint64 sent, qint64 total);
|
|
||||||
};
|
|
||||||
|
|
||||||
class FluHttp : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY_AUTO(int,retry);
|
|
||||||
Q_PROPERTY_AUTO(int,timeout)
|
|
||||||
Q_PROPERTY_AUTO(int,cacheMode);
|
|
||||||
Q_PROPERTY_AUTO(QString,cacheDir);
|
|
||||||
Q_PROPERTY_AUTO(bool,breakPointDownload);
|
|
||||||
QML_NAMED_ELEMENT(FluHttp)
|
|
||||||
private:
|
|
||||||
QVariant invokeIntercept(QMap<QString, QVariant> request);
|
|
||||||
void addQueryParam(QUrl* url,const QMap<QString, QVariant>& params);
|
|
||||||
void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& params);
|
|
||||||
void handleCache(const QString& httpId, const QString& result);
|
|
||||||
QString readCache(const QString& httpId);
|
|
||||||
bool cacheExists(const QString& httpId);
|
|
||||||
QString getCacheFilePath(const QString& httpId);
|
|
||||||
void onStart(QPointer<HttpCallable> callable);
|
|
||||||
void onFinish(QPointer<HttpCallable> callable,QPointer<HttpRequest> request);
|
|
||||||
void onError(QPointer<HttpCallable> callable,int status,QString errorString,QString result);
|
|
||||||
void onSuccess(QPointer<HttpCallable> callable,QString result);
|
|
||||||
void onCache(QPointer<HttpCallable> callable,QString result);
|
|
||||||
void onDownloadProgress(QPointer<HttpCallable> callable,qint64 recv,qint64 total);
|
|
||||||
void onUploadProgress(QPointer<HttpCallable> callable,qint64 sent,qint64 total);
|
|
||||||
public:
|
|
||||||
explicit FluHttp(QObject *parent = nullptr);
|
|
||||||
~FluHttp();
|
|
||||||
Q_INVOKABLE HttpRequest* newRequest(QString url = "");
|
|
||||||
Q_INVOKABLE void get(HttpRequest* request,HttpCallable* callable);
|
|
||||||
Q_INVOKABLE void post(HttpRequest* request,HttpCallable* callable);
|
|
||||||
Q_INVOKABLE void postString(HttpRequest* request,HttpCallable* callable);
|
|
||||||
Q_INVOKABLE void postJson(HttpRequest* request,HttpCallable* callable);
|
|
||||||
Q_INVOKABLE void download(HttpRequest* request,HttpCallable* callable);
|
|
||||||
Q_INVOKABLE void upload(HttpRequest* request,HttpCallable* callable);
|
|
||||||
Q_INVOKABLE void deleteResource(HttpRequest* request,HttpCallable* callable);
|
|
||||||
Q_INVOKABLE qreal getBreakPointProgress(HttpRequest* request);
|
|
||||||
Q_INVOKABLE void cancel();
|
|
||||||
private:
|
|
||||||
QList<QPointer<QNetworkReply>> _cacheReply;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FLUHTTP_H
|
|
@ -1,4 +0,0 @@
|
|||||||
#include "FluHttpInterceptor.h"
|
|
||||||
|
|
||||||
FluHttpInterceptor::FluHttpInterceptor(QObject *parent):QObject{parent}{
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
#ifndef FLUHTTPINTERCEPTOR_H
|
|
||||||
#define FLUHTTPINTERCEPTOR_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QtQml/qqml.h>
|
|
||||||
|
|
||||||
class FluHttpInterceptor : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
QML_NAMED_ELEMENT(FluHttpInterceptor)
|
|
||||||
public:
|
|
||||||
explicit FluHttpInterceptor(QObject *parent = nullptr);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FLUHTTPINTERCEPTOR_H
|
|
663
src/FluNetwork.cpp
Normal file
663
src/FluNetwork.cpp
Normal file
@ -0,0 +1,663 @@
|
|||||||
|
#include "FluNetwork.h"
|
||||||
|
|
||||||
|
#include <QUrlQuery>
|
||||||
|
#include <QBuffer>
|
||||||
|
#include <QHttpMultiPart>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QNetworkDiskCache>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <QQmlContext>
|
||||||
|
#include <QJSEngine>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QThreadPool>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QEventLoop>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
|
||||||
|
NetworkCallable::NetworkCallable(QObject *parent):QObject{parent}{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString NetworkParams::method2String(){
|
||||||
|
switch (_method) {
|
||||||
|
case METHOD_GET:
|
||||||
|
return "GET";
|
||||||
|
case METHOD_HEAD:
|
||||||
|
return "HEAD";
|
||||||
|
case METHOD_POST:
|
||||||
|
return "POST";
|
||||||
|
case METHOD_PUT:
|
||||||
|
return "PUT";
|
||||||
|
case METHOD_PATCH:
|
||||||
|
return "PATCH";
|
||||||
|
case METHOD_DELETE:
|
||||||
|
return "DELETE";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetworkParams::getTimeout(){
|
||||||
|
if(_timeout != -1){
|
||||||
|
return _timeout;
|
||||||
|
}
|
||||||
|
return FluNetwork::getInstance()->timeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetworkParams::getRetry(){
|
||||||
|
if(_retry != -1){
|
||||||
|
return _retry;
|
||||||
|
}
|
||||||
|
return FluNetwork::getInstance()->retry();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetworkParams::getOpenLog(){
|
||||||
|
if(!_openLog.isNull()){
|
||||||
|
return _openLog.toBool();
|
||||||
|
}
|
||||||
|
return FluNetwork::getInstance()->openLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadParam::DownloadParam(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadParam::DownloadParam(QString destPath,bool append,QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
this->_destPath = destPath;
|
||||||
|
this->_append = append;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams::NetworkParams(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams::NetworkParams(QString url,Type type,Method method,QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
this->_method = method;
|
||||||
|
this->_url = url;
|
||||||
|
this->_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* NetworkParams::add(QString key,QVariant val){
|
||||||
|
_paramMap.insert(key,val);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* NetworkParams::addFile(QString key,QVariant val){
|
||||||
|
_fileMap.insert(key,val);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* NetworkParams::addHeader(QString key,QVariant val){
|
||||||
|
_headerMap.insert(key,val);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* NetworkParams::addQuery(QString key,QVariant val){
|
||||||
|
_queryMap.insert(key,val);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* NetworkParams::setBody(QString val){
|
||||||
|
_body = val;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* NetworkParams::setTimeout(int val){
|
||||||
|
_timeout = val;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* NetworkParams::setRetry(int val){
|
||||||
|
_retry = val;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* NetworkParams::setCacheMode(int val){
|
||||||
|
_cacheMode = val;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* NetworkParams::toDownload(QString destPath,bool append){
|
||||||
|
_downloadParam = new DownloadParam(destPath,append,this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* NetworkParams::bind(QObject* target){
|
||||||
|
_target = target;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* NetworkParams::openLog(QVariant val){
|
||||||
|
_openLog = val;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString NetworkParams::buildCacheKey(){
|
||||||
|
QJsonObject obj;
|
||||||
|
obj.insert("url",_url);
|
||||||
|
obj.insert("method",method2String());
|
||||||
|
obj.insert("body",_body);
|
||||||
|
obj.insert("query",QJsonDocument::fromVariant(_queryMap).object());
|
||||||
|
obj.insert("param",QJsonDocument::fromVariant(_paramMap).object());
|
||||||
|
obj.insert("header",QJsonDocument::fromVariant(_headerMap).object());
|
||||||
|
obj.insert("file",QJsonDocument::fromVariant(_fileMap).object());
|
||||||
|
if(_downloadParam){
|
||||||
|
QJsonObject downObj;
|
||||||
|
downObj.insert("destPath",_downloadParam->_destPath);
|
||||||
|
downObj.insert("append",_downloadParam->_append);
|
||||||
|
obj.insert("download",downObj);
|
||||||
|
}
|
||||||
|
QByteArray data = QJsonDocument(obj).toJson(QJsonDocument::Compact);
|
||||||
|
return QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkParams::go(NetworkCallable* callable){
|
||||||
|
QJSValueList data;
|
||||||
|
data<<qjsEngine(FluNetwork::getInstance())->newQObject(this);
|
||||||
|
FluNetwork::getInstance()->_interceptor.call(data);
|
||||||
|
if(_downloadParam){
|
||||||
|
FluNetwork::getInstance()->handleDownload(this,callable);
|
||||||
|
}else{
|
||||||
|
FluNetwork::getInstance()->handle(this,callable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluNetwork::handle(NetworkParams* params,NetworkCallable* c){
|
||||||
|
QPointer<NetworkCallable> callable(c);
|
||||||
|
QThreadPool::globalInstance()->start([=](){
|
||||||
|
if(!callable.isNull()){
|
||||||
|
callable->start();
|
||||||
|
}
|
||||||
|
QString cacheKey = params->buildCacheKey();
|
||||||
|
if(params->_cacheMode == FluNetworkType::CacheMode::FirstCacheThenRequest && cacheExists(cacheKey)){
|
||||||
|
if(!callable.isNull()){
|
||||||
|
callable->cache(readCache(cacheKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(params->_cacheMode == FluNetworkType::CacheMode::IfNoneCacheRequest && cacheExists(cacheKey)){
|
||||||
|
if(!callable.isNull()){
|
||||||
|
callable->cache(readCache(cacheKey));
|
||||||
|
callable->finish();
|
||||||
|
params->deleteLater();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QNetworkAccessManager manager;
|
||||||
|
manager.setTransferTimeout(params->getTimeout());
|
||||||
|
QEventLoop loop;
|
||||||
|
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
||||||
|
for (int i = 0; i < params->getRetry(); ++i) {
|
||||||
|
QUrl url(params->_url);
|
||||||
|
addQueryParam(&url,params->_queryMap);
|
||||||
|
QNetworkRequest request(url);
|
||||||
|
addHeaders(&request,params->_headerMap);
|
||||||
|
QNetworkReply* reply;
|
||||||
|
sendRequest(&manager,request,params,reply,i==0,callable);
|
||||||
|
if(!QPointer<QGuiApplication>(qApp)){
|
||||||
|
reply->deleteLater();
|
||||||
|
reply = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto abortCallable = [&loop,reply,&i,params]{
|
||||||
|
if(reply){
|
||||||
|
i = params->getRetry();
|
||||||
|
reply->abort();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
QMetaObject::Connection conn_destoryed = {};
|
||||||
|
QMetaObject::Connection conn_quit = {};
|
||||||
|
if(params->_target){
|
||||||
|
conn_destoryed = connect(params->_target,&QObject::destroyed,&manager,abortCallable);
|
||||||
|
}
|
||||||
|
conn_quit = connect(qApp,&QGuiApplication::aboutToQuit,&manager, abortCallable);
|
||||||
|
loop.exec();
|
||||||
|
if(conn_destoryed){
|
||||||
|
disconnect(conn_destoryed);
|
||||||
|
}
|
||||||
|
if(conn_quit){
|
||||||
|
disconnect(conn_quit);
|
||||||
|
}
|
||||||
|
QString response;
|
||||||
|
if(params->_method == NetworkParams::METHOD_HEAD){
|
||||||
|
response = headerList2String(reply->rawHeaderPairs());
|
||||||
|
}else{
|
||||||
|
if(reply->isOpen()){
|
||||||
|
response = QString::fromUtf8(reply->readAll());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
if(httpStatus == 200){
|
||||||
|
if(!callable.isNull()){
|
||||||
|
if(params->_cacheMode != FluNetworkType::CacheMode::NoCache){
|
||||||
|
saveResponse(cacheKey,response);
|
||||||
|
}
|
||||||
|
callable->success(response);
|
||||||
|
}
|
||||||
|
printRequestEndLog(request,params,reply,response);
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
if(i == params->getRetry()-1){
|
||||||
|
if(!callable.isNull()){
|
||||||
|
if(params->_cacheMode == FluNetworkType::CacheMode::RequestFailedReadCache && cacheExists(cacheKey)){
|
||||||
|
if(!callable.isNull()){
|
||||||
|
callable->cache(readCache(cacheKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callable->error(httpStatus,reply->errorString(),response);
|
||||||
|
}
|
||||||
|
printRequestEndLog(request,params,reply,response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
params->deleteLater();
|
||||||
|
if(!callable.isNull()){
|
||||||
|
callable->finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluNetwork::handleDownload(NetworkParams* params,NetworkCallable* c){
|
||||||
|
QPointer<NetworkCallable> callable(c);
|
||||||
|
QThreadPool::globalInstance()->start([=](){
|
||||||
|
if(!callable.isNull()){
|
||||||
|
callable->start();
|
||||||
|
}
|
||||||
|
QString cacheKey = params->buildCacheKey();
|
||||||
|
QUrl url(params->_url);
|
||||||
|
QNetworkAccessManager manager;
|
||||||
|
manager.setTransferTimeout(params->getTimeout());
|
||||||
|
addQueryParam(&url,params->_queryMap);
|
||||||
|
QNetworkRequest request(url);
|
||||||
|
addHeaders(&request,params->_headerMap);
|
||||||
|
QString cachePath = getCacheFilePath(cacheKey);
|
||||||
|
QString destPath = params->_downloadParam->_destPath;
|
||||||
|
QFile* destFile = new QFile(destPath);
|
||||||
|
QFile* cacheFile = new QFile(cachePath);
|
||||||
|
bool isOpen = false;
|
||||||
|
qint64 seek = 0;
|
||||||
|
if(cacheFile->exists() && destFile->exists() && params->_downloadParam->_append){
|
||||||
|
QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(cacheKey).toUtf8()).object();
|
||||||
|
qint64 fileSize = cacheInfo.value("fileSize").toDouble();
|
||||||
|
qint64 contentLength = cacheInfo.value("contentLength").toDouble();
|
||||||
|
if(fileSize == contentLength && destFile->size() == contentLength){
|
||||||
|
if(!callable.isNull()){
|
||||||
|
callable->downloadProgress(fileSize,contentLength);
|
||||||
|
callable->success(destPath);
|
||||||
|
callable->finish();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(fileSize==destFile->size()){
|
||||||
|
request.setRawHeader("Range", QString("bytes=%1-").arg(fileSize).toUtf8());
|
||||||
|
seek = fileSize;
|
||||||
|
isOpen = destFile->open(QIODevice::WriteOnly|QIODevice::Append);
|
||||||
|
}else{
|
||||||
|
isOpen = destFile->open(QIODevice::WriteOnly|QIODevice::Truncate);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
isOpen = destFile->open(QIODevice::WriteOnly|QIODevice::Truncate);
|
||||||
|
}
|
||||||
|
if(!isOpen){
|
||||||
|
if(!callable.isNull()){
|
||||||
|
callable->error(-1,"device not open","");
|
||||||
|
callable->finish();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(params->_downloadParam->_append){
|
||||||
|
if (!cacheFile->open(QIODevice::WriteOnly|QIODevice::Truncate))
|
||||||
|
{
|
||||||
|
if(!callable.isNull()){
|
||||||
|
callable->error(-1,"cache file device not open","");
|
||||||
|
callable->finish();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QEventLoop loop;
|
||||||
|
QNetworkReply *reply = manager.get(request);
|
||||||
|
destFile->setParent(reply);
|
||||||
|
cacheFile->setParent(reply);
|
||||||
|
auto abortCallable = [&loop,reply,params]{
|
||||||
|
if(reply){
|
||||||
|
reply->abort();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
||||||
|
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
||||||
|
QMetaObject::Connection conn_destoryed = {};
|
||||||
|
QMetaObject::Connection conn_quit = {};
|
||||||
|
if(params->_target){
|
||||||
|
conn_destoryed = connect(params->_target,&QObject::destroyed,&manager,abortCallable);
|
||||||
|
}
|
||||||
|
conn_quit = connect(qApp,&QGuiApplication::aboutToQuit,&manager, abortCallable);
|
||||||
|
connect(reply,&QNetworkReply::readyRead,reply,[reply,seek,destFile,cacheFile,callable]{
|
||||||
|
if (!reply || !destFile || reply->error() != QNetworkReply::NoError)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QMap<QString, QVariant> downInfo;
|
||||||
|
qint64 contentLength = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong()+seek;
|
||||||
|
downInfo.insert("contentLength",contentLength);
|
||||||
|
QString eTag = reply->header(QNetworkRequest::ETagHeader).toString();
|
||||||
|
downInfo.insert("eTag",eTag);
|
||||||
|
destFile->write(reply->readAll());
|
||||||
|
destFile->flush();
|
||||||
|
downInfo.insert("fileSize",destFile->size());
|
||||||
|
if(cacheFile->isOpen()){
|
||||||
|
cacheFile->resize(0);
|
||||||
|
cacheFile->write(QJsonDocument::fromVariant(QVariant(downInfo)).toJson().toBase64());
|
||||||
|
cacheFile->flush();
|
||||||
|
}
|
||||||
|
if(!callable.isNull()){
|
||||||
|
callable->downloadProgress(destFile->size(),contentLength);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
loop.exec();
|
||||||
|
if(conn_destoryed){
|
||||||
|
disconnect(conn_destoryed);
|
||||||
|
}
|
||||||
|
if(conn_quit){
|
||||||
|
disconnect(conn_quit);
|
||||||
|
}
|
||||||
|
params->deleteLater();
|
||||||
|
reply->deleteLater();
|
||||||
|
if(!callable.isNull()){
|
||||||
|
callable->finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FluNetwork::readCache(const QString& key){
|
||||||
|
auto filePath = getCacheFilePath(key);
|
||||||
|
QString result;
|
||||||
|
QFile file(filePath);
|
||||||
|
if(!file.exists()){
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
|
QTextStream stream(&file);
|
||||||
|
result = QString(QByteArray::fromBase64(stream.readAll().toUtf8()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FluNetwork::cacheExists(const QString& key){
|
||||||
|
return QFile(getCacheFilePath(key)).exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FluNetwork::getCacheFilePath(const QString& key){
|
||||||
|
QDir cacheDir(_cacheDir);
|
||||||
|
if(!cacheDir.exists()){
|
||||||
|
cacheDir.mkpath(_cacheDir);
|
||||||
|
}
|
||||||
|
return cacheDir.absoluteFilePath(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FluNetwork::headerList2String(const QList<QNetworkReply::RawHeaderPair>& data){
|
||||||
|
QJsonObject object;
|
||||||
|
for (auto it = data.constBegin(); it != data.constEnd(); ++it) {
|
||||||
|
object.insert(QString(it->first),QString(it->second));
|
||||||
|
}
|
||||||
|
return QJsonDocument(object).toJson(QJsonDocument::Compact);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FluNetwork::map2String(const QMap<QString, QVariant>& map){
|
||||||
|
QStringList parameters;
|
||||||
|
for (auto it = map.constBegin(); it != map.constEnd(); ++it) {
|
||||||
|
parameters << QString("%1=%2").arg(it.key(), it.value().toString());
|
||||||
|
}
|
||||||
|
return parameters.join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,bool isFirst,QPointer<NetworkCallable> callable){
|
||||||
|
QByteArray verb = params->method2String().toUtf8();
|
||||||
|
switch (params->_type) {
|
||||||
|
case NetworkParams::TYPE_FORM:{
|
||||||
|
bool isFormData = !params->_fileMap.isEmpty();
|
||||||
|
if(isFormData){
|
||||||
|
QHttpMultiPart *multiPart = new QHttpMultiPart();
|
||||||
|
multiPart->setContentType(QHttpMultiPart::FormDataType);
|
||||||
|
for (const auto& each : params->_paramMap.toStdMap())
|
||||||
|
{
|
||||||
|
QHttpPart part;
|
||||||
|
part.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"").arg(each.first));
|
||||||
|
part.setBody(each.second.toByteArray());
|
||||||
|
multiPart->append(part);
|
||||||
|
}
|
||||||
|
for (const auto& each : params->_fileMap.toStdMap())
|
||||||
|
{
|
||||||
|
QString filePath = each.second.toString();
|
||||||
|
QString name = each.first;
|
||||||
|
QFile *file = new QFile(filePath);
|
||||||
|
QString fileName = QFileInfo(filePath).fileName();
|
||||||
|
file->open(QIODevice::ReadOnly);
|
||||||
|
file->setParent(multiPart);
|
||||||
|
QHttpPart part;
|
||||||
|
part.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"; filename=\"%2\"").arg(name,fileName));
|
||||||
|
part.setBodyDevice(file);
|
||||||
|
multiPart->append(part);
|
||||||
|
}
|
||||||
|
reply = manager->sendCustomRequest(request,verb,multiPart);
|
||||||
|
multiPart->setParent(reply);
|
||||||
|
connect(reply,&QNetworkReply::uploadProgress,reply,[callable](qint64 bytesSent, qint64 bytesTotal){
|
||||||
|
if(!callable.isNull() && bytesSent!=0 && bytesTotal!=0){
|
||||||
|
Q_EMIT callable->uploadProgress(bytesSent,bytesTotal);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/x-www-form-urlencoded"));
|
||||||
|
QString value;
|
||||||
|
for (const auto& each : params->_paramMap.toStdMap())
|
||||||
|
{
|
||||||
|
value += QString("%1=%2").arg(each.first,each.second.toString());
|
||||||
|
value += "&";
|
||||||
|
}
|
||||||
|
if(!params->_paramMap.isEmpty()){
|
||||||
|
value.chop(1);
|
||||||
|
}
|
||||||
|
QByteArray data = value.toUtf8();
|
||||||
|
reply = manager->sendCustomRequest(request,verb,data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NetworkParams::TYPE_JSON:{
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json;charset=utf-8"));
|
||||||
|
QJsonObject json;
|
||||||
|
for (const auto& each : params->_paramMap.toStdMap())
|
||||||
|
{
|
||||||
|
json.insert(each.first,each.second.toJsonValue());
|
||||||
|
}
|
||||||
|
QByteArray data = QJsonDocument(json).toJson(QJsonDocument::Compact);
|
||||||
|
reply = manager->sendCustomRequest(request,verb,data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NetworkParams::TYPE_JSONARRAY:{
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json;charset=utf-8"));
|
||||||
|
QJsonArray jsonArray;
|
||||||
|
for (const auto& each : params->_paramMap.toStdMap())
|
||||||
|
{
|
||||||
|
QJsonObject json;
|
||||||
|
json.insert(each.first,each.second.toJsonValue());
|
||||||
|
jsonArray.append(json);
|
||||||
|
}
|
||||||
|
QByteArray data = QJsonDocument(jsonArray).toJson(QJsonDocument::Compact);
|
||||||
|
reply = manager->sendCustomRequest(request,params->method2String().toUtf8(),data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NetworkParams::TYPE_BODY:{
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("text/plain;charset=utf-8"));
|
||||||
|
QByteArray data = params->_body.toUtf8();
|
||||||
|
reply = manager->sendCustomRequest(request,verb,data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
reply = manager->sendCustomRequest(request,verb);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(isFirst){
|
||||||
|
printRequestStartLog(request,params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluNetwork::printRequestStartLog(QNetworkRequest request,NetworkParams* params){
|
||||||
|
if(!params->getOpenLog()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug()<<"<------"<<qUtf8Printable(request.header(QNetworkRequest::UserAgentHeader).toString())<<"Request Start ------>";
|
||||||
|
qDebug()<<qUtf8Printable(QString::fromStdString("<%1>").arg(params->method2String()))<<qUtf8Printable(params->_url);
|
||||||
|
auto contentType = request.header(QNetworkRequest::ContentTypeHeader).toString();
|
||||||
|
if(!contentType.isEmpty()){
|
||||||
|
qDebug()<<qUtf8Printable(QString::fromStdString("<Header> %1=%2").arg("Content-Type",contentType));
|
||||||
|
}
|
||||||
|
QList<QByteArray> headers = request.rawHeaderList();
|
||||||
|
for(const QByteArray& header:headers){
|
||||||
|
qDebug()<<qUtf8Printable(QString::fromStdString("<Header> %1=%2").arg(header,request.rawHeader(header)));
|
||||||
|
}
|
||||||
|
if(!params->_queryMap.isEmpty()){
|
||||||
|
qDebug()<<"<Query>"<<qUtf8Printable(map2String(params->_queryMap));
|
||||||
|
}
|
||||||
|
if(!params->_paramMap.isEmpty()){
|
||||||
|
qDebug()<<"<Param>"<<qUtf8Printable(map2String(params->_paramMap));
|
||||||
|
}
|
||||||
|
if(!params->_fileMap.isEmpty()){
|
||||||
|
qDebug()<<"<File>"<<qUtf8Printable(map2String(params->_fileMap));
|
||||||
|
}
|
||||||
|
if(!params->_body.isEmpty()){
|
||||||
|
qDebug()<<"<Body>"<<qUtf8Printable(params->_body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluNetwork::printRequestEndLog(QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,const QString& response){
|
||||||
|
if(!params->getOpenLog()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug()<<"<------"<<qUtf8Printable(request.header(QNetworkRequest::UserAgentHeader).toString())<<"Request End ------>";
|
||||||
|
qDebug()<<qUtf8Printable(QString::fromStdString("<%1>").arg(params->method2String()))<<qUtf8Printable(params->_url);
|
||||||
|
qDebug()<<"<Result>"<<qUtf8Printable(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluNetwork::saveResponse(QString key,QString response){
|
||||||
|
QSharedPointer<QFile> file(new QFile(getCacheFilePath(key)));
|
||||||
|
QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate;
|
||||||
|
if (!file->open(mode))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
file->write(response.toUtf8().toBase64());
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluNetwork::addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers){
|
||||||
|
request->setHeader(QNetworkRequest::UserAgentHeader,QString::fromStdString("Mozilla/5.0 %1/%2").arg(QGuiApplication::applicationName(),QGuiApplication::applicationVersion()));
|
||||||
|
QMapIterator<QString, QVariant> iter(headers);
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
iter.next();
|
||||||
|
request->setRawHeader(iter.key().toUtf8(), iter.value().toString().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluNetwork::addQueryParam(QUrl* url,const QMap<QString, QVariant>& params){
|
||||||
|
QMapIterator<QString, QVariant> iter(params);
|
||||||
|
QUrlQuery urlQuery(*url);
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
iter.next();
|
||||||
|
urlQuery.addQueryItem(iter.key(), iter.value().toString());
|
||||||
|
}
|
||||||
|
url->setQuery(urlQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
FluNetwork::FluNetwork(QObject *parent): QObject{parent}
|
||||||
|
{
|
||||||
|
timeout(5000);
|
||||||
|
retry(3);
|
||||||
|
openLog(false);
|
||||||
|
cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation).append(QDir::separator()).append("network"));
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::get(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_NONE,NetworkParams::METHOD_GET,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::head(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_NONE,NetworkParams::METHOD_HEAD,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::postBody(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_POST,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::putBody(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_PUT,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::patchBody(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_PATCH,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::deleteBody(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_DELETE,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::postForm(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_POST,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::putForm(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_PUT,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::patchForm(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_PATCH,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::deleteForm(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_DELETE,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::postJson(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_POST,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::putJson(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_PUT,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::patchJson(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_PATCH,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::deleteJson(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_DELETE,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::postJsonArray(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_POST,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::putJsonArray(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_PUT,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::patchJsonArray(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_PATCH,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkParams* FluNetwork::deleteJsonArray(const QString& url){
|
||||||
|
return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_DELETE,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluNetwork::setInterceptor(QJSValue interceptor){
|
||||||
|
this->_interceptor = interceptor;
|
||||||
|
}
|
146
src/FluNetwork.h
Normal file
146
src/FluNetwork.h
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#ifndef FLUNETWORK_H
|
||||||
|
#define FLUNETWORK_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QtQml/qqml.h>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QJsonValue>
|
||||||
|
#include <QJSValue>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include "Def.h"
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "singleton.h"
|
||||||
|
|
||||||
|
class NetworkCallable : public QObject{
|
||||||
|
Q_OBJECT
|
||||||
|
QML_NAMED_ELEMENT(FluNetworkCallable)
|
||||||
|
public:
|
||||||
|
explicit NetworkCallable(QObject *parent = nullptr);
|
||||||
|
Q_SIGNAL void start();
|
||||||
|
Q_SIGNAL void finish();
|
||||||
|
Q_SIGNAL void error(int status,QString errorString,QString result);
|
||||||
|
Q_SIGNAL void success(QString result);
|
||||||
|
Q_SIGNAL void cache(QString result);
|
||||||
|
Q_SIGNAL void uploadProgress(qint64 sent, qint64 total);
|
||||||
|
Q_SIGNAL void downloadProgress(qint64 recv, qint64 total);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DownloadParam : public QObject{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DownloadParam(QObject *parent = nullptr);
|
||||||
|
DownloadParam(QString destPath,bool append,QObject *parent = nullptr);
|
||||||
|
public:
|
||||||
|
QString _destPath;
|
||||||
|
bool _append;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NetworkParams : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
QML_NAMED_ELEMENT(FluNetworkParams)
|
||||||
|
public:
|
||||||
|
enum Method{
|
||||||
|
METHOD_GET,
|
||||||
|
METHOD_HEAD,
|
||||||
|
METHOD_POST,
|
||||||
|
METHOD_PUT,
|
||||||
|
METHOD_PATCH,
|
||||||
|
METHOD_DELETE
|
||||||
|
};
|
||||||
|
enum Type{
|
||||||
|
TYPE_NONE,
|
||||||
|
TYPE_FORM,
|
||||||
|
TYPE_JSON,
|
||||||
|
TYPE_JSONARRAY,
|
||||||
|
TYPE_BODY
|
||||||
|
};
|
||||||
|
explicit NetworkParams(QObject *parent = nullptr);
|
||||||
|
NetworkParams(QString url,Type type,Method method,QObject *parent = nullptr);
|
||||||
|
Q_INVOKABLE NetworkParams* addQuery(QString key,QVariant val);
|
||||||
|
Q_INVOKABLE NetworkParams* addHeader(QString key,QVariant val);
|
||||||
|
Q_INVOKABLE NetworkParams* add(QString key,QVariant val);
|
||||||
|
Q_INVOKABLE NetworkParams* addFile(QString key,QVariant val);
|
||||||
|
Q_INVOKABLE NetworkParams* setBody(QString val);
|
||||||
|
Q_INVOKABLE NetworkParams* setTimeout(int val);
|
||||||
|
Q_INVOKABLE NetworkParams* setRetry(int val);
|
||||||
|
Q_INVOKABLE NetworkParams* setCacheMode(int val);
|
||||||
|
Q_INVOKABLE NetworkParams* toDownload(QString destPath,bool append = false);
|
||||||
|
Q_INVOKABLE NetworkParams* bind(QObject* target);
|
||||||
|
Q_INVOKABLE NetworkParams* openLog(QVariant val);
|
||||||
|
Q_INVOKABLE void go(NetworkCallable* result);
|
||||||
|
QString buildCacheKey();
|
||||||
|
QString method2String();
|
||||||
|
int getTimeout();
|
||||||
|
int getRetry();
|
||||||
|
bool getOpenLog();
|
||||||
|
public:
|
||||||
|
DownloadParam* _downloadParam = nullptr;
|
||||||
|
QObject* _target = nullptr;
|
||||||
|
Method _method;
|
||||||
|
Type _type;
|
||||||
|
QString _url;
|
||||||
|
QString _body;
|
||||||
|
QMap<QString, QVariant> _queryMap;
|
||||||
|
QMap<QString, QVariant> _headerMap;
|
||||||
|
QMap<QString, QVariant> _paramMap;
|
||||||
|
QMap<QString, QVariant> _fileMap;
|
||||||
|
int _timeout = -1;
|
||||||
|
int _retry = -1;
|
||||||
|
QVariant _openLog;
|
||||||
|
int _cacheMode = FluNetworkType::CacheMode::NoCache;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FluNetwork : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY_AUTO(int,timeout)
|
||||||
|
Q_PROPERTY_AUTO(int,retry)
|
||||||
|
Q_PROPERTY_AUTO(QString,cacheDir)
|
||||||
|
Q_PROPERTY_AUTO(bool,openLog)
|
||||||
|
QML_NAMED_ELEMENT(FluNetwork)
|
||||||
|
QML_SINGLETON
|
||||||
|
private:
|
||||||
|
explicit FluNetwork(QObject *parent = nullptr);
|
||||||
|
public:
|
||||||
|
SINGLETONG(FluNetwork)
|
||||||
|
static FluNetwork *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
|
||||||
|
Q_INVOKABLE NetworkParams* get(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* head(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* postBody(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* putBody(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* patchBody(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* deleteBody(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* postForm(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* putForm(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* patchForm(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* deleteForm(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* postJson(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* putJson(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* patchJson(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* deleteJson(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* postJsonArray(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* putJsonArray(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* patchJsonArray(const QString& url);
|
||||||
|
Q_INVOKABLE NetworkParams* deleteJsonArray(const QString& url);
|
||||||
|
Q_INVOKABLE void setInterceptor(QJSValue interceptor);
|
||||||
|
void handle(NetworkParams* params,NetworkCallable* result);
|
||||||
|
void handleDownload(NetworkParams* params,NetworkCallable* result);
|
||||||
|
private:
|
||||||
|
void sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,bool isFirst,QPointer<NetworkCallable> callable);
|
||||||
|
void addQueryParam(QUrl* url,const QMap<QString, QVariant>& params);
|
||||||
|
void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers);
|
||||||
|
void saveResponse(QString key,QString response);
|
||||||
|
QString readCache(const QString& key);
|
||||||
|
bool cacheExists(const QString& key);
|
||||||
|
QString getCacheFilePath(const QString& key);
|
||||||
|
QString map2String(const QMap<QString, QVariant>& map);
|
||||||
|
QString headerList2String(const QList<QNetworkReply::RawHeaderPair>& data);
|
||||||
|
void printRequestStartLog(QNetworkRequest request,NetworkParams* params);
|
||||||
|
void printRequestEndLog(QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,const QString& response);
|
||||||
|
public:
|
||||||
|
QJSValue _interceptor;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FLUNETWORK_H
|
@ -11,26 +11,26 @@ FluTextStyle::FluTextStyle(QObject *parent):QObject{parent}{
|
|||||||
|
|
||||||
QFont bodyStrong;
|
QFont bodyStrong;
|
||||||
bodyStrong.setPixelSize(13);
|
bodyStrong.setPixelSize(13);
|
||||||
bodyStrong.setBold(true);
|
bodyStrong.setWeight(QFont::DemiBold);
|
||||||
BodyStrong(bodyStrong);
|
BodyStrong(bodyStrong);
|
||||||
|
|
||||||
QFont subtitle;
|
QFont subtitle;
|
||||||
subtitle.setPixelSize(20);
|
subtitle.setPixelSize(20);
|
||||||
subtitle.setBold(true);
|
subtitle.setWeight(QFont::DemiBold);
|
||||||
Subtitle(subtitle);
|
Subtitle(subtitle);
|
||||||
|
|
||||||
QFont title;
|
QFont title;
|
||||||
title.setPixelSize(28);
|
title.setPixelSize(28);
|
||||||
title.setBold(true);
|
title.setWeight(QFont::DemiBold);
|
||||||
Title(title);
|
Title(title);
|
||||||
|
|
||||||
QFont titleLarge;
|
QFont titleLarge;
|
||||||
titleLarge.setPixelSize(40);
|
titleLarge.setPixelSize(40);
|
||||||
titleLarge.setBold(true);
|
titleLarge.setWeight(QFont::DemiBold);
|
||||||
TitleLarge(titleLarge);
|
TitleLarge(titleLarge);
|
||||||
|
|
||||||
QFont display;
|
QFont display;
|
||||||
display.setPixelSize(68);
|
display.setPixelSize(68);
|
||||||
display.setBold(true);
|
display.setWeight(QFont::DemiBold);
|
||||||
Display(display);
|
Display(display);
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,31 @@ FluTheme::FluTheme(QObject *parent):QObject{parent}{
|
|||||||
connect(this,&FluTheme::darkModeChanged,this,[=]{
|
connect(this,&FluTheme::darkModeChanged,this,[=]{
|
||||||
Q_EMIT darkChanged();
|
Q_EMIT darkChanged();
|
||||||
});
|
});
|
||||||
primaryColor(FluColors::getInstance()->Blue());
|
connect(this,&FluTheme::darkChanged,this,[=]{refreshColors();});
|
||||||
|
connect(this,&FluTheme::themeColorChanged,this,[=]{refreshColors();});
|
||||||
|
themeColor(FluColors::getInstance()->Blue());
|
||||||
|
darkMode(FluThemeType::DarkMode::Light);
|
||||||
nativeText(false);
|
nativeText(false);
|
||||||
enableAnimation(true);
|
enableAnimation(true);
|
||||||
darkMode(FluThemeType::DarkMode::Light);
|
|
||||||
_systemDark = systemDark();
|
_systemDark = systemDark();
|
||||||
qApp->installEventFilter(this);
|
qApp->installEventFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FluTheme::refreshColors(){
|
||||||
|
auto isDark = dark();
|
||||||
|
primaryColor(isDark ? _themeColor->lighter() : _themeColor->dark());
|
||||||
|
backgroundColor(isDark ? QColor(0,0,0,255) : QColor(1,1,1,255));
|
||||||
|
windowBackgroundColor(isDark ? QColor(32,32,32,255) : QColor(237,237,237,255));
|
||||||
|
windowActiveBackgroundColor(isDark ? QColor(26,26,26,255) : QColor(243,243,243,255));
|
||||||
|
fontPrimaryColor(isDark ? QColor(248,248,248,255) : QColor(7,7,7,255));
|
||||||
|
fontSecondaryColor(isDark ? QColor(222,222,222,255) : QColor(102,102,102,255));
|
||||||
|
fontTertiaryColor(isDark ? QColor(200,200,200,255) : QColor(153,153,153,255));
|
||||||
|
itemNormalColor(isDark ? QColor(255,255,255,0) : QColor(0,0,0,0));
|
||||||
|
itemHoverColor(isDark ? QColor(255,255,255,255*0.03) : QColor(0,0,0,255*0.03));
|
||||||
|
itemPressColor(isDark ? QColor(255,255,255,255*0.06) : QColor(0,0,0,255*0.06));
|
||||||
|
itemCheckColor(isDark ? QColor(255,255,255,255*0.09) : QColor(0,0,0,255*0.09));
|
||||||
|
}
|
||||||
|
|
||||||
bool FluTheme::eventFilter(QObject *obj, QEvent *event){
|
bool FluTheme::eventFilter(QObject *obj, QEvent *event){
|
||||||
Q_UNUSED(obj);
|
Q_UNUSED(obj);
|
||||||
if (event->type() == QEvent::ApplicationPaletteChange || event->type() == QEvent::ThemeChange)
|
if (event->type() == QEvent::ApplicationPaletteChange || event->type() == QEvent::ThemeChange)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QtQml/qqml.h>
|
#include <QtQml/qqml.h>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <QColor>
|
||||||
#include "FluColorSet.h"
|
#include "FluColorSet.h"
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "singleton.h"
|
#include "singleton.h"
|
||||||
@ -16,7 +17,18 @@ class FluTheme : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(bool dark READ dark NOTIFY darkChanged)
|
Q_PROPERTY(bool dark READ dark NOTIFY darkChanged)
|
||||||
Q_PROPERTY_AUTO(FluColorSet*,primaryColor)
|
Q_PROPERTY_AUTO(FluColorSet*,themeColor);
|
||||||
|
Q_PROPERTY_AUTO(QColor,primaryColor);
|
||||||
|
Q_PROPERTY_AUTO(QColor,backgroundColor);
|
||||||
|
Q_PROPERTY_AUTO(QColor,windowBackgroundColor);
|
||||||
|
Q_PROPERTY_AUTO(QColor,windowActiveBackgroundColor);
|
||||||
|
Q_PROPERTY_AUTO(QColor,fontPrimaryColor);
|
||||||
|
Q_PROPERTY_AUTO(QColor,fontSecondaryColor);
|
||||||
|
Q_PROPERTY_AUTO(QColor,fontTertiaryColor);
|
||||||
|
Q_PROPERTY_AUTO(QColor,itemNormalColor);
|
||||||
|
Q_PROPERTY_AUTO(QColor,itemHoverColor);
|
||||||
|
Q_PROPERTY_AUTO(QColor,itemPressColor);
|
||||||
|
Q_PROPERTY_AUTO(QColor,itemCheckColor);
|
||||||
Q_PROPERTY_AUTO(int,darkMode);
|
Q_PROPERTY_AUTO(int,darkMode);
|
||||||
Q_PROPERTY_AUTO(bool,nativeText);
|
Q_PROPERTY_AUTO(bool,nativeText);
|
||||||
Q_PROPERTY_AUTO(bool,enableAnimation);
|
Q_PROPERTY_AUTO(bool,enableAnimation);
|
||||||
@ -26,6 +38,7 @@ private:
|
|||||||
explicit FluTheme(QObject *parent = nullptr);
|
explicit FluTheme(QObject *parent = nullptr);
|
||||||
bool eventFilter(QObject *obj, QEvent *event);
|
bool eventFilter(QObject *obj, QEvent *event);
|
||||||
bool systemDark();
|
bool systemDark();
|
||||||
|
void refreshColors();
|
||||||
public:
|
public:
|
||||||
SINGLETONG(FluTheme)
|
SINGLETONG(FluTheme)
|
||||||
Q_INVOKABLE QJsonArray awesomeList(const QString& keyword = "");
|
Q_INVOKABLE QJsonArray awesomeList(const QString& keyword = "");
|
||||||
@ -33,7 +46,6 @@ public:
|
|||||||
static FluTheme *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
|
static FluTheme *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
|
||||||
bool dark();
|
bool dark();
|
||||||
private:
|
private:
|
||||||
bool _dark;
|
|
||||||
bool _systemDark;
|
bool _systemDark;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -175,3 +175,7 @@ QPoint FluTools::cursorPos(){
|
|||||||
qint64 FluTools::currentTimestamp(){
|
qint64 FluTools::currentTimestamp(){
|
||||||
return QDateTime::currentMSecsSinceEpoch();
|
return QDateTime::currentMSecsSinceEpoch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QIcon FluTools::windowIcon(){
|
||||||
|
return QGuiApplication::windowIcon();
|
||||||
|
}
|
||||||
|
@ -49,6 +49,7 @@ public:
|
|||||||
Q_INVOKABLE bool isSoftware();
|
Q_INVOKABLE bool isSoftware();
|
||||||
Q_INVOKABLE qint64 currentTimestamp();
|
Q_INVOKABLE qint64 currentTimestamp();
|
||||||
Q_INVOKABLE QPoint cursorPos();
|
Q_INVOKABLE QPoint cursorPos();
|
||||||
|
Q_INVOKABLE QIcon windowIcon();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FLUTOOLS_H
|
#endif // FLUTOOLS_H
|
||||||
|
@ -35,7 +35,9 @@ bool ViewModelManager::exist(const QString& key){
|
|||||||
void ViewModelManager::refreshViewModel(FluViewModel* viewModel,QString key,QVariant value){
|
void ViewModelManager::refreshViewModel(FluViewModel* viewModel,QString key,QVariant value){
|
||||||
foreach (auto item, _viewmodel) {
|
foreach (auto item, _viewmodel) {
|
||||||
if(item->getKey() == viewModel->getKey()){
|
if(item->getKey() == viewModel->getKey()){
|
||||||
item->setProperty(key.toStdString().c_str(),value);
|
item->enablePropertyChange = false;
|
||||||
|
item->setProperty(key.toLatin1().constData(),value);
|
||||||
|
item->enablePropertyChange = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,14 +53,16 @@ PropertyObserver::~PropertyObserver(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PropertyObserver::_propertyChange(){
|
void PropertyObserver::_propertyChange(){
|
||||||
auto value = _property.read();
|
auto viewModel = (FluViewModel*)parent();
|
||||||
_model->setProperty(_name.toStdString().c_str(),value);
|
if(viewModel->enablePropertyChange){
|
||||||
ViewModelManager::getInstance()->refreshViewModel((FluViewModel*)parent(),_name,value);
|
auto value = _property.read();
|
||||||
|
_model->setProperty(_name.toLatin1().constData(),value);
|
||||||
|
ViewModelManager::getInstance()->refreshViewModel(viewModel,_name,value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FluViewModel::FluViewModel(QObject *parent):QObject{parent}{
|
FluViewModel::FluViewModel(QObject *parent):QObject{parent}{
|
||||||
scope(FluViewModelType::Scope::Window);
|
scope(FluViewModelType::Scope::Window);
|
||||||
target(nullptr);
|
|
||||||
ViewModelManager::getInstance()->insertViewModel(this);
|
ViewModelManager::getInstance()->insertViewModel(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +81,7 @@ void FluViewModel::componentComplete(){
|
|||||||
}
|
}
|
||||||
const QMetaObject* obj = metaObject();
|
const QMetaObject* obj = metaObject();
|
||||||
if(_scope == FluViewModelType::Scope::Window){
|
if(_scope == FluViewModelType::Scope::Window){
|
||||||
_key = property("objectName_").toString()+QString::number(reinterpret_cast<qulonglong>(_window), 16);
|
_key = property("objectName").toString()+"-"+QString::number(reinterpret_cast<qulonglong>(_window), 16);
|
||||||
}else{
|
}else{
|
||||||
_key = property("objectName").toString();
|
_key = property("objectName").toString();
|
||||||
}
|
}
|
||||||
@ -93,7 +97,7 @@ void FluViewModel::componentComplete(){
|
|||||||
const QMetaProperty property = obj->property(i);
|
const QMetaProperty property = obj->property(i);
|
||||||
QString propertyName = property.name();
|
QString propertyName = property.name();
|
||||||
auto value = property.read(this);
|
auto value = property.read(this);
|
||||||
model->setProperty(propertyName.toStdString().c_str(),value);
|
model->setProperty(propertyName.toLatin1().constData(),value);
|
||||||
new PropertyObserver(propertyName,model,this);
|
new PropertyObserver(propertyName,model,this);
|
||||||
}
|
}
|
||||||
ViewModelManager::getInstance()->insert(_key,model);
|
ViewModelManager::getInstance()->insert(_key,model);
|
||||||
|
@ -20,7 +20,6 @@ class FluViewModel : public QObject, public QQmlParserStatus
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(QQmlParserStatus)
|
Q_INTERFACES(QQmlParserStatus)
|
||||||
Q_PROPERTY_AUTO(int,scope);
|
Q_PROPERTY_AUTO(int,scope);
|
||||||
Q_PROPERTY_AUTO(QObject*,target);
|
|
||||||
QML_NAMED_ELEMENT(FluViewModel)
|
QML_NAMED_ELEMENT(FluViewModel)
|
||||||
public:
|
public:
|
||||||
explicit FluViewModel(QObject *parent = nullptr);
|
explicit FluViewModel(QObject *parent = nullptr);
|
||||||
@ -29,6 +28,7 @@ public:
|
|||||||
void componentComplete() override;
|
void componentComplete() override;
|
||||||
Q_SIGNAL void initData();
|
Q_SIGNAL void initData();
|
||||||
QString getKey();
|
QString getKey();
|
||||||
|
bool enablePropertyChange = true;
|
||||||
private:
|
private:
|
||||||
QObject* _window = nullptr;
|
QObject* _window = nullptr;
|
||||||
QString _key = "";
|
QString _key = "";
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user