mirror of
https://github.com/zhuzichu520/FluentUI.git
synced 2025-07-03 08:35:28 +08:00
update
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import FluentUI 1.0
|
||||
|
||||
FluWindow {
|
||||
@ -12,18 +13,60 @@ FluWindow {
|
||||
title:"关于"
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"关于"
|
||||
fontStyle: FluText.Display
|
||||
anchors.centerIn: parent
|
||||
ColumnLayout{
|
||||
anchors{
|
||||
top: appbar.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
RowLayout{
|
||||
Layout.topMargin: 20
|
||||
Layout.leftMargin: 15
|
||||
spacing: 14
|
||||
FluText{
|
||||
text:"FluentUI"
|
||||
fontStyle: FluText.Title
|
||||
}
|
||||
FluText{
|
||||
text:"v1.0.0.0"
|
||||
fontStyle: FluText.Body
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
spacing: 14
|
||||
Layout.topMargin: 20
|
||||
Layout.leftMargin: 15
|
||||
FluText{
|
||||
text:"作者:"
|
||||
}
|
||||
FluText{
|
||||
text:"朱子楚"
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
spacing: 14
|
||||
Layout.topMargin: 20
|
||||
Layout.leftMargin: 15
|
||||
FluText{
|
||||
text:"GitHub:"
|
||||
}
|
||||
FluTextButton{
|
||||
id:text_hublink
|
||||
text:"https://github.com/zhuzichu520/FluentUI"
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
onClicked: {
|
||||
Qt.openUrlExternally(text_hublink.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -9,16 +9,23 @@ Window {
|
||||
id:app
|
||||
color: "#00000000"
|
||||
Component.onCompleted: {
|
||||
FluApp.isFps = true
|
||||
|
||||
FluApp.setContextProperty("installHelper",installHelper)
|
||||
|
||||
FluApp.isDark = false
|
||||
FluApp.setAppWindow(app)
|
||||
FluApp.routes = {
|
||||
"/":"qrc:/MainPage.qml",
|
||||
"/Setting":"qrc:/SettingPage.qml",
|
||||
"/About":"qrc:/AboutPage.qml",
|
||||
"/Installer":"qrc:/Installer.qml"
|
||||
"/Installer":"qrc:/Installer.qml",
|
||||
"/Uninstall":"qrc:/Uninstall.qml"
|
||||
}
|
||||
if(installHelper.isNavigateUninstall()){
|
||||
FluApp.initialRoute = "/Uninstall"
|
||||
}else{
|
||||
FluApp.initialRoute = "/Installer"
|
||||
}
|
||||
FluApp.initialRoute = "/Installer"
|
||||
FluApp.run()
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,105 @@
|
||||
#include "InstallHelper.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QCoreApplication>
|
||||
#include <QtConcurrent>
|
||||
|
||||
#include <windows.h>
|
||||
#include <shobjidl.h>
|
||||
#include <shlguid.h>
|
||||
|
||||
#pragma comment(lib, "User32.lib")
|
||||
#pragma comment(lib, "Ole32.lib")
|
||||
|
||||
|
||||
using CopyProgressCallback = std::function<void(int currentFile, int totalFiles)>;
|
||||
|
||||
|
||||
static void copyDir(const QString& srcPath, const QString& dstPath, CopyProgressCallback callback)
|
||||
{
|
||||
QDir srcDir(srcPath);
|
||||
QDir dstDir(dstPath);
|
||||
if (!dstDir.exists()) {
|
||||
dstDir.mkdir(dstPath);
|
||||
}
|
||||
QFileInfoList fileInfos = srcDir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
int totalFiles = fileInfos.count();
|
||||
int currentFile = 0;
|
||||
foreach (QFileInfo fileInfo, fileInfos) {
|
||||
currentFile++;
|
||||
QString srcFilePath = fileInfo.filePath();
|
||||
QString dstFilePath = dstPath + QDir::separator() + fileInfo.fileName();
|
||||
if (fileInfo.isDir()) {
|
||||
copyDir(srcFilePath, dstFilePath, callback);
|
||||
} else {
|
||||
QFile dstFile(dstFilePath);
|
||||
if(dstFile.exists()){
|
||||
dstFile.remove();
|
||||
}
|
||||
QFile::copy(srcFilePath, dstFilePath);
|
||||
}
|
||||
if (callback != nullptr) {
|
||||
callback(currentFile, totalFiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void createHome(const QString& exePath,const QString& linkName){
|
||||
//创建桌面快捷方式
|
||||
QFile::link(exePath, QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).append("/").append(linkName));
|
||||
}
|
||||
|
||||
static void createUninstallLink(QString exePath, QString path, QString uninstallLinkName){
|
||||
#ifdef Q_OS_WIN
|
||||
QString dst = path.append("\\").append(uninstallLinkName);
|
||||
IShellLink *pShellLink;
|
||||
QString args = "--uninstall";
|
||||
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_IShellLink, (LPVOID *)&pShellLink);
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
// 设置快捷方式的目标路径和参数
|
||||
pShellLink->SetPath(exePath.toStdWString().c_str());
|
||||
pShellLink->SetArguments(args.toStdWString().c_str());
|
||||
|
||||
// 设置快捷方式的描述
|
||||
pShellLink->SetDescription(L"Fluent Uninstall");
|
||||
|
||||
// 获取IPersistFile接口
|
||||
IPersistFile *pPersistFile;
|
||||
hres = pShellLink->QueryInterface(IID_IPersistFile, (LPVOID *)&pPersistFile);
|
||||
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
// 保存快捷方式到文件
|
||||
hres = pPersistFile->Save(dst.toStdWString().c_str(), TRUE);
|
||||
pPersistFile->Release();
|
||||
}
|
||||
pShellLink->Release();
|
||||
}
|
||||
CoUninitialize();
|
||||
|
||||
// std::string dst = path.append("\\").append(uninstallLinkName).toStdString();
|
||||
|
||||
// QFile::link(exePath,QString::fromStdString(dst + " --uninstall"));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void createStartMenu(const QString& exePath,const QString& fileName,const QString& linkName){
|
||||
//创建开始菜单快捷方式
|
||||
QString startMenuPath=QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation).append("/").append(fileName);
|
||||
QDir dir(startMenuPath);
|
||||
if(!dir.exists())
|
||||
{
|
||||
dir.mkdir(startMenuPath);
|
||||
}
|
||||
if(dir.exists())
|
||||
{
|
||||
QFile::link(exePath, startMenuPath.append("/").append(linkName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
InstallHelper::InstallHelper(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
@ -7,6 +107,32 @@ InstallHelper::InstallHelper(QObject *parent)
|
||||
}
|
||||
|
||||
void InstallHelper::install(const QString& path,bool isHome,bool isStartMenu){
|
||||
installing(true);
|
||||
qDebug()<<path;
|
||||
QtConcurrent::run([=](){
|
||||
installing(true);
|
||||
QFuture<void> future = QtConcurrent::run(copyDir,QCoreApplication::applicationDirPath(),path,[=](int currentFile, int totalFiles){
|
||||
if(currentFile==totalFiles){
|
||||
QString exePath = path+"\\"+"example.exe";
|
||||
QString fileName = "FluentUI";
|
||||
QString linkName = "FluentUI.lnk";
|
||||
QString uninstallLinkName = "Uninstall FluentUI.lnk";
|
||||
if(isHome){
|
||||
createHome(exePath,linkName);
|
||||
}
|
||||
if(isStartMenu){
|
||||
createStartMenu(exePath,fileName,linkName);
|
||||
}
|
||||
createUninstallLink(exePath,path,uninstallLinkName);
|
||||
}
|
||||
});
|
||||
future.waitForFinished();
|
||||
qDebug()<<QCoreApplication::applicationDirPath();
|
||||
qDebug()<<path;
|
||||
installing(false);
|
||||
});
|
||||
}
|
||||
|
||||
void InstallHelper::uninstall(){
|
||||
QString currentDir = QCoreApplication::applicationDirPath();
|
||||
QDir dir(currentDir);
|
||||
dir.removeRecursively();
|
||||
}
|
||||
|
@ -2,18 +2,32 @@
|
||||
#define INSTALLHELPER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QGuiApplication>
|
||||
#include <QDebug>
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
class InstallHelper : public QObject
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(bool,installing)
|
||||
public:
|
||||
explicit InstallHelper(QObject *parent = nullptr);
|
||||
|
||||
Q_INVOKABLE void install(const QString& path,bool isHome,bool isStartMenu);
|
||||
signals:
|
||||
|
||||
Q_INVOKABLE QString applicationFilePath(){
|
||||
return QGuiApplication::arguments().join(" ");
|
||||
}
|
||||
|
||||
Q_INVOKABLE bool isNavigateUninstall(){
|
||||
return true;
|
||||
// return QGuiApplication::arguments().contains("--uninstall");
|
||||
}
|
||||
|
||||
Q_INVOKABLE void uninstall();
|
||||
|
||||
};
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Dialogs 1.3 as Dialogs
|
||||
import Qt.labs.platform 1.1
|
||||
import UI 1.0
|
||||
import FluentUI 1.0
|
||||
|
||||
FluWindow {
|
||||
@ -27,9 +26,6 @@ FluWindow {
|
||||
|
||||
Item{
|
||||
id:data
|
||||
InstallHelper{
|
||||
id:helper
|
||||
}
|
||||
Dialogs.FileDialog {
|
||||
id: fileDialog
|
||||
selectFolder: true
|
||||
@ -72,7 +68,8 @@ FluWindow {
|
||||
text:"更改路径"
|
||||
Layout.rightMargin: 30
|
||||
onClicked: {
|
||||
fileDialog.open()
|
||||
showInfo(installHelper.applicationFilePath())
|
||||
// fileDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -122,7 +119,7 @@ FluWindow {
|
||||
FluFilledButton{
|
||||
text:"同意并安装"
|
||||
onClicked: {
|
||||
helper.install(textbox_path.text,checkbox_home.checked,checkbox_startmenu.checked)
|
||||
installHelper.install(textbox_path.text,checkbox_home.checked,checkbox_startmenu.checked)
|
||||
}
|
||||
}
|
||||
FluButton{
|
||||
@ -139,7 +136,7 @@ FluWindow {
|
||||
Rectangle{
|
||||
|
||||
anchors.fill: parent
|
||||
visible: helper.installing
|
||||
visible: installHelper.installing
|
||||
color: "#80000000"
|
||||
|
||||
MouseArea{
|
||||
|
@ -17,6 +17,8 @@ FluWindow {
|
||||
FluAppBar{
|
||||
id:appbar
|
||||
title: "FluentUI"
|
||||
showDark: true
|
||||
showFps: true
|
||||
}
|
||||
|
||||
Item{
|
||||
@ -75,18 +77,24 @@ FluWindow {
|
||||
id:menu
|
||||
x:40
|
||||
margins:4
|
||||
FluMenuItem{
|
||||
text:"意见反馈"
|
||||
onClicked:{
|
||||
showInfo("正在建设中...")
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text:"关于"
|
||||
onClicked:{
|
||||
FluApp.navigate("/About")
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text:"设置"
|
||||
onClicked:{
|
||||
FluApp.navigate("/Setting")
|
||||
}
|
||||
}
|
||||
// FluMenuItem{
|
||||
// text:"设置"
|
||||
// onClicked:{
|
||||
// FluApp.navigate("/Setting")
|
||||
// }
|
||||
// }
|
||||
}
|
||||
onClicked:{
|
||||
menu.open()
|
||||
|
@ -79,9 +79,6 @@ Item {
|
||||
source: "qrc:/res/svg/avatar_1.svg"
|
||||
sourceSize: Qt.size(width,height)
|
||||
}
|
||||
layer.enabled: true
|
||||
layer.effect: FluDropShadow {}
|
||||
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
@ -93,8 +90,6 @@ Item {
|
||||
sourceSize: Qt.size(width,height)
|
||||
source: "qrc:/res/svg/avatar_2.svg"
|
||||
}
|
||||
layer.enabled: true
|
||||
layer.effect: FluDropShadow {}
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
@ -106,12 +101,6 @@ Item {
|
||||
sourceSize: Qt.size(width,height)
|
||||
source: "qrc:/res/svg/avatar_3.svg"
|
||||
}
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
radius: 5
|
||||
samples: 4
|
||||
color: "#80000000"
|
||||
}
|
||||
}
|
||||
FluRectangle{
|
||||
width: 50
|
||||
@ -123,8 +112,6 @@ Item {
|
||||
sourceSize: Qt.size(width,height)
|
||||
source: "qrc:/res/svg/avatar_4.svg"
|
||||
}
|
||||
layer.enabled: true
|
||||
layer.effect: FluDropShadow {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,12 +126,6 @@ Item {
|
||||
sourceSize: Qt.size(width,height)
|
||||
}
|
||||
Layout.topMargin: 10
|
||||
layer.enabled: true
|
||||
layer.effect: FluDropShadow {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
68
example/Uninstall.qml
Normal file
68
example/Uninstall.qml
Normal file
@ -0,0 +1,68 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Dialogs 1.3 as Dialogs
|
||||
import Qt.labs.platform 1.1
|
||||
import FluentUI 1.0
|
||||
|
||||
FluWindow {
|
||||
|
||||
id:window
|
||||
width: 800
|
||||
height: 400
|
||||
minimumWidth:800
|
||||
maximumWidth:800
|
||||
minimumHeight:400
|
||||
maximumHeight:400
|
||||
title:"卸载向导"
|
||||
|
||||
FluAppBar{
|
||||
id:appbar
|
||||
title: "卸载向导"
|
||||
}
|
||||
|
||||
ColumnLayout{
|
||||
|
||||
width: parent.width
|
||||
|
||||
anchors{
|
||||
top: appbar.bottom
|
||||
bottom: parent.bottom
|
||||
topMargin: 20
|
||||
}
|
||||
|
||||
Item{
|
||||
width: 1
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
Rectangle{
|
||||
|
||||
Layout.fillWidth: true
|
||||
border.width: 1
|
||||
border.color: FluApp.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(238/255,238/255,238/255,1)
|
||||
|
||||
height: 60
|
||||
color: FluApp.isDark ? "#323232" : "#FFFFFF"
|
||||
RowLayout{
|
||||
anchors{
|
||||
right: parent.right
|
||||
rightMargin: 30
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
spacing: 14
|
||||
FluButton{
|
||||
text:"取消"
|
||||
onClicked: {
|
||||
window.close()
|
||||
}
|
||||
}
|
||||
FluButton{
|
||||
text:"确定要卸载"
|
||||
onClicked: {
|
||||
installHelper.uninstall()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
QT += quick
|
||||
QT += quick concurrent
|
||||
CONFIG += c++11
|
||||
|
||||
DEFINES += QT_DEPRECATED_WARNINGS QT_NO_WARNING_OUTPUT
|
||||
@ -13,37 +13,6 @@ qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
|
||||
|
||||
#### 如果你正在使用静态库.a 那么你还需要将下面的配置注释取消掉。
|
||||
#### 其它项目使用方法也是如此。
|
||||
|
||||
# DEFINES += STATICLIB
|
||||
|
||||
# LIBNAME = FluentUI
|
||||
|
||||
# CONFIG(debug, debug|release) {
|
||||
# contains(QMAKE_HOST.os,Windows) {
|
||||
# LIBNAME = FluentUId
|
||||
# }else{
|
||||
# LIBNAME = FluentUI_debug
|
||||
# }
|
||||
# }
|
||||
|
||||
# # Additional import path used to resolve QML modules in Qt Creator's code model
|
||||
# QML_IMPORT_PATH = $$OUT_PWD/../bin/
|
||||
|
||||
# # Additional import path used to resolve QML modules just for Qt Quick Designer
|
||||
# QML_DESIGNER_IMPORT_PATH = $$OUT_PWD/../bin/
|
||||
|
||||
# INCLUDEPATH += $$OUT_PWD/../bin/FluentUI/
|
||||
# DEPENDPATH += $$OUT_PWD/../bin/FluentUI/
|
||||
|
||||
# LIBS += -L$$OUT_PWD/../bin/FluentUI/ -l$${LIBNAME}
|
||||
# PRE_TARGETDEPS += $$OUT_PWD/../bin/FluentUI/lib$${LIBNAME}.a
|
||||
|
||||
### 注意:静态库 .so .dylib .dll 是自动安装的Qt qml plugin目录中,不需要此步配置
|
||||
|
||||
HEADERS += \
|
||||
InstallHelper.h \
|
||||
stdafx.h
|
||||
|
@ -1,35 +1,18 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQmlContext>
|
||||
#include "InstallHelper.h"
|
||||
|
||||
#if defined(STATICLIB)
|
||||
#include <FluentUI.h>
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setOrganizationName("ZhuZiChu");
|
||||
QCoreApplication::setOrganizationDomain("https://zhuzichu520.github.io");
|
||||
QCoreApplication::setApplicationName("FluentUI");
|
||||
|
||||
qputenv("QSG_RENDER_LOOP","basic");
|
||||
QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
|
||||
#endif
|
||||
// QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication app(argc, argv);
|
||||
QQmlApplicationEngine engine;
|
||||
|
||||
qmlRegisterType<InstallHelper>("UI",1,0,"InstallHelper");
|
||||
|
||||
#if defined(STATICLIB)
|
||||
FluentUI::create(&engine);
|
||||
#endif
|
||||
qDebug()<<"setContextProperty------->1";
|
||||
engine.rootContext()->setContextProperty("installHelper",new InstallHelper());
|
||||
const QUrl url(QStringLiteral("qrc:/App.qml"));
|
||||
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
|
||||
&app, [url](QObject *obj, const QUrl &objUrl) {
|
||||
|
@ -27,5 +27,6 @@
|
||||
<file>Installer.qml</file>
|
||||
<file>T_Awesome.qml</file>
|
||||
<file>T_TextBox.qml</file>
|
||||
<file>Uninstall.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Reference in New Issue
Block a user