Browse Source

http模块有问题,需要修改

lennlouis 2 weeks ago
commit
9d8c7baa36
66 changed files with 4602 additions and 0 deletions
  1. 2 0
      .gitignore
  2. 16 0
      core_form/core_form.pri
  3. 14 0
      core_form/frmalbum/frmalbum.cpp
  4. 22 0
      core_form/frmalbum/frmalbum.h
  5. 8 0
      core_form/frmalbum/frmalbum.pri
  6. 19 0
      core_form/frmalbum/frmalbum.ui
  7. 92 0
      core_form/frmimgshow/frmimgshow.cpp
  8. 50 0
      core_form/frmimgshow/frmimgshow.h
  9. 5 0
      core_form/frmimgshow/frmimgshow.pri
  10. 129 0
      core_form/frmsetting/frmsetting.cpp
  11. 47 0
      core_form/frmsetting/frmsetting.h
  12. 8 0
      core_form/frmsetting/frmsetting.pri
  13. 364 0
      core_form/frmsetting/frmsetting.ui
  14. 103 0
      core_form/frmupload/frmupload.cpp
  15. 42 0
      core_form/frmupload/frmupload.h
  16. 8 0
      core_form/frmupload/frmupload.pri
  17. 158 0
      core_form/frmupload/frmupload.ui
  18. 48 0
      core_form/serversetting/serversetting.cpp
  19. 33 0
      core_form/serversetting/serversetting.h
  20. 8 0
      core_form/serversetting/serversetting.pri
  21. 101 0
      core_form/serversetting/serversetting.ui
  22. 473 0
      core_form/switchbutton/switchbutton.cpp
  23. 159 0
      core_form/switchbutton/switchbutton.h
  24. 5 0
      core_form/switchbutton/switchbutton.pri
  25. 6 0
      core_support/core_support.pri
  26. 149 0
      core_support/fileconfigdecode/fileconfigdecode.cpp
  27. 51 0
      core_support/fileconfigdecode/fileconfigdecode.h
  28. 5 0
      core_support/fileconfigdecode/fileconfigdecode.pri
  29. 351 0
      core_support/tchttpservice/tchttpservice.cpp
  30. 68 0
      core_support/tchttpservice/tchttpservice.h
  31. 5 0
      core_support/tchttpservice/tchttpservice.pri
  32. 5 0
      core_ui/core_ui.pri
  33. 377 0
      core_ui/iconhelper.cpp
  34. 184 0
      core_ui/iconhelper.h
  35. 17 0
      image.qrc
  36. BIN
      libcrypto.a
  37. BIN
      libcrypto.dll.a
  38. BIN
      libssl.a
  39. BIN
      libssl.dll.a
  40. 23 0
      main.cpp
  41. 47 0
      picpanel.pro
  42. 319 0
      picpanel.pro.user
  43. 270 0
      picpanel/picpanel.pro.user
  44. BIN
      qrc/image/album_blue.png
  45. BIN
      qrc/image/album_white.png
  46. BIN
      qrc/image/copy_blue.png
  47. BIN
      qrc/image/copy_white.png
  48. BIN
      qrc/image/delete_red.png
  49. BIN
      qrc/image/delete_white.png
  50. BIN
      qrc/image/icon.png
  51. BIN
      qrc/image/info_blue.png
  52. BIN
      qrc/image/info_grey.png
  53. BIN
      qrc/image/setting_blue.png
  54. BIN
      qrc/image/setting_white.png
  55. BIN
      qrc/image/upload_blue.png
  56. BIN
      qrc/image/upload_white.png
  57. 192 0
      qrc/qss/blacksoft.qss
  58. BIN
      qrc/ttf/fa-regular-400.ttf
  59. BIN
      qrc/ttf/fontawesome-webfont.ttf
  60. BIN
      qrc/ttf/iconfont.ttf
  61. BIN
      qrc/ttf/pe-icon-set-weather.ttf
  62. 5 0
      qss.qrc
  63. 8 0
      ttf.qrc
  64. 353 0
      widget.cpp
  65. 77 0
      widget.h
  66. 176 0
      widget.ui

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+build/
+.DS_Store

+ 16 - 0
core_form/core_form.pri

@@ -0,0 +1,16 @@
+CONFIG += QMAKE_CXXFLAGS_WARN_OFF
+
+INCLUDEPATH += $$PWD
+INCLUDEPATH += $$PWD/frmupload
+INCLUDEPATH += $$PWD/frmsetting
+INCLUDEPATH += $$PWD/frmalbum
+INCLUDEPATH += $$PWD/frmimgshow
+INCLUDEPATH += $$PWD/switchbutton
+INCLUDEPATH += $$PWD/serversetting
+
+include($$PWD/frmupload/frmupload.pri)
+include($$PWD/frmsetting/frmsetting.pri)
+include($$PWD/frmalbum/frmalbum.pri)
+include($$PWD/frmimgshow/frmimgshow.pri)
+include($$PWD/switchbutton/switchbutton.pri)
+include($$PWD/serversetting/serversetting.pri)

+ 14 - 0
core_form/frmalbum/frmalbum.cpp

@@ -0,0 +1,14 @@
+#include "frmalbum.h"
+#include "ui_frmalbum.h"
+
+FrmAlbum::FrmAlbum(QWidget *parent)
+    : QWidget(parent)
+    , ui(new Ui::FrmAlbum)
+{
+    ui->setupUi(this);
+}
+
+FrmAlbum::~FrmAlbum()
+{
+    delete ui;
+}

+ 22 - 0
core_form/frmalbum/frmalbum.h

@@ -0,0 +1,22 @@
+#ifndef FRMALBUM_H
+#define FRMALBUM_H
+
+#include <QWidget>
+
+namespace Ui {
+class FrmAlbum;
+}
+
+class FrmAlbum : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit FrmAlbum(QWidget *parent = nullptr);
+    ~FrmAlbum();
+
+private:
+    Ui::FrmAlbum *ui;
+};
+
+#endif // FRMALBUM_H

+ 8 - 0
core_form/frmalbum/frmalbum.pri

@@ -0,0 +1,8 @@
+FORMS += \
+    $$PWD/frmalbum.ui
+
+HEADERS += \
+    $$PWD/frmalbum.h
+
+SOURCES += \
+    $$PWD/frmalbum.cpp

+ 19 - 0
core_form/frmalbum/frmalbum.ui

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FrmAlbum</class>
+ <widget class="QWidget" name="FrmAlbum">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 92 - 0
core_form/frmimgshow/frmimgshow.cpp

@@ -0,0 +1,92 @@
+#include "frmimgshow.h"
+
+FrmImgShow::FrmImgShow(QString& url, QWidget *parent) : QWidget(parent)
+{
+    initForm();
+    initForm();
+    initManager();
+    this->url = url;
+    manager->get(QNetworkRequest(QUrl(url)));
+}
+
+bool FrmImgShow::eventFilter(QObject *watched, QEvent *event)
+{
+    if (watched == btnCopy) {
+        if (event->type() == QEvent::Enter) {
+            btnCopy->setIcon(QIcon(QPixmap(":/qrc/image/copy_blue.png")));
+            return true;
+        }
+        else if (event->type() == QEvent::Leave) {
+            btnCopy->setIcon(QIcon(QPixmap(":/qrc/image/copy_white.png")));
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    if (watched == btnDelete) {
+        if (event->type() == QEvent::Enter) {
+            btnDelete->setIcon(QIcon(QPixmap(":/qrc/image/delete_red.png")));
+            return true;
+        }
+        else if (event->type() == QEvent::Leave) {
+            btnDelete->setIcon(QIcon(QPixmap(":/qrc/image/delete_white.png")));
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    return QWidget::eventFilter(watched, event);
+}
+
+void FrmImgShow::onFinished(QNetworkReply *reply)
+{
+    if (reply->error() == QNetworkReply::NoError) {
+        QByteArray imageData = reply->readAll();
+        QPixmap pix;
+        pix.loadFromData(imageData);
+        this->labImg->setPixmap(pix);
+    }
+}
+
+void FrmImgShow::initForm()
+{
+    labImg = new QLabel();
+    btnCopy = new QToolButton();
+    btnDelete = new QToolButton();
+    horizenSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+    hLayout = new QHBoxLayout();
+    vLayout = new QVBoxLayout();
+
+    hLayout->addWidget(btnCopy);
+    hLayout->addSpacerItem(horizenSpacer);
+    vLayout->addWidget(labImg);
+    vLayout->addLayout(hLayout);
+    this->setLayout(vLayout);
+
+    btnCopy->setIcon(QIcon(QPixmap(":/qrc/image/copy_white.png")));
+    btnDelete->setIcon(QIcon(QPixmap(":/qrc/image/delete_white.png")));
+    btnCopy->setFixedSize(32, 32);
+    btnCopy->setCursor(Qt::PointingHandCursor);
+}
+
+void FrmImgShow::initWidget()
+{
+    btnCopy->installEventFilter(this);
+    btnDelete->installEventFilter(this);
+}
+
+void FrmImgShow::initManager()
+{
+    manager = new QNetworkAccessManager();
+    QClipboard* clipboard = QGuiApplication::clipboard();
+    connect(manager, &QNetworkAccessManager::finished,
+            this, &FrmImgShow::onFinished);
+
+    connect(btnCopy, &QToolButton::clicked, [&](){
+        clipboard->setText(this->url);
+    });
+}

+ 50 - 0
core_form/frmimgshow/frmimgshow.h

@@ -0,0 +1,50 @@
+#ifndef FRMIMGSHOW_H
+#define FRMIMGSHOW_H
+
+#include <QWidget>
+#include <QPushButton>
+#include <QLabel>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QToolButton>
+#include <QSpacerItem>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QUrl>
+#include <QNetworkReply>
+#include <QClipboard>
+#include <QGuiApplication>
+
+class FrmImgShow : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit FrmImgShow(QString& url, QWidget *parent = nullptr);
+
+private:
+    QLabel* labImg;
+    QToolButton* btnCopy;
+    QToolButton* btnDelete;
+    QSpacerItem* horizenSpacer;
+    QHBoxLayout* hLayout;
+    QVBoxLayout* vLayout;
+
+    QNetworkAccessManager* manager;
+    QString url;
+
+protected:
+    virtual bool eventFilter(QObject* watched, QEvent* event);
+
+private slots:
+    void onFinished(QNetworkReply *reply);
+
+private:
+    void initForm();
+    void initWidget();
+    void initManager();
+
+signals:
+
+};
+
+#endif // FRMIMGSHOW_H

+ 5 - 0
core_form/frmimgshow/frmimgshow.pri

@@ -0,0 +1,5 @@
+HEADERS += \
+    $$PWD/frmimgshow.h
+
+SOURCES += \
+    $$PWD/frmimgshow.cpp

+ 129 - 0
core_form/frmsetting/frmsetting.cpp

@@ -0,0 +1,129 @@
+#include "frmsetting.h"
+#include "ui_frmsetting.h"
+#include <QDebug>
+
+FrmSetting::FrmSetting(FileConfigDecode* fileConfig, QWidget *parent)
+    : QWidget(parent)
+    , ui(new Ui::FrmSetting)
+{
+    ui->setupUi(this);
+    this->fileConfig = fileConfig;
+    initForm();
+    initWidget();
+}
+
+FrmSetting::~FrmSetting()
+{
+    delete ui;
+}
+
+void FrmSetting::initForm()
+{
+    ui->schRename->setBgColorOn(QColor("#409EFF"));
+    ui->schRename->enableText(false);
+    ui->schRename->setAnimation(true);
+
+
+    ui->schAutoSetup->setBgColorOn(QColor("#409EFF"));
+    ui->schAutoSetup->enableText(false);
+    ui->schAutoSetup->setAnimation(true);
+
+
+    ui->schTimeRename->setBgColorOn(QColor("#409EFF"));
+    ui->schTimeRename->enableText(false);
+    ui->schTimeRename->setAnimation(true);
+
+
+    ui->schEnableSsl->setBgColorOn(QColor("#409EFF"));
+    ui->schEnableSsl->enableText(false);
+    ui->schEnableSsl->setAnimation(true);
+
+    ui->btnServer->setCursor(Qt::PointingHandCursor);
+    ui->schRename->setCursor(Qt::PointingHandCursor);
+
+
+    serversetting = new ServerSetting();
+    serversetting->hide();
+
+}
+
+void FrmSetting::initWidget()
+{
+    if (fileConfig->getRename()) {
+        ui->labRenameOpen->setStyleSheet(OPENQSS);
+        ui->labRenameClose->setStyleSheet(CLOSEQSS);
+    }
+    else {
+        ui->labRenameOpen->setStyleSheet(CLOSEQSS);
+        ui->labRenameClose->setStyleSheet(OPENQSS);
+    }
+    if (fileConfig->getAutoSetup()) {
+        ui->labAutoSetupOpen->setStyleSheet(OPENQSS);
+        ui->labAutoSetupClose->setStyleSheet(CLOSEQSS);
+    }
+    else {
+        ui->labAutoSetupOpen->setStyleSheet(CLOSEQSS);
+        ui->labAutoSetupClose->setStyleSheet(OPENQSS);
+    }
+    if (fileConfig->getTimeRename()) {
+        ui->labTimeRenameOpen->setStyleSheet(OPENQSS);
+        ui->labTimeRenameClose->setStyleSheet(CLOSEQSS);
+    }
+    else {
+        ui->labTimeRenameOpen->setStyleSheet(CLOSEQSS);
+        ui->labTimeRenameClose->setStyleSheet(OPENQSS);
+    }
+    if (fileConfig->getAutoCopy()) {
+        ui->labEnableSsl->setStyleSheet(OPENQSS);
+        ui->labEnableSsl->setStyleSheet(CLOSEQSS);
+    }
+    else {
+        ui->labEnableSsl->setStyleSheet(CLOSEQSS);
+        ui->labEnableSsl->setStyleSheet(OPENQSS);
+    }
+
+    ui->schRename->setChecked(fileConfig->getRename());
+    ui->schAutoSetup->setChecked(fileConfig->getAutoSetup());
+    ui->schTimeRename->setChecked(fileConfig->getTimeRename());
+    ui->schEnableSsl->setChecked(fileConfig->getAutoCopy());
+
+    connect(ui->schRename, &SwitchButton::checkedChanged, this, &FrmSetting::schRenameSlot);
+    connect(ui->schAutoSetup, &SwitchButton::checkedChanged, this, &FrmSetting::schAutoSetup);
+    connect(ui->schTimeRename, &SwitchButton::checkedChanged, this, &FrmSetting::schTimeRename);
+    connect(ui->schEnableSsl, &SwitchButton::checkedChanged, this, &FrmSetting::schEnableSsl);
+    connect(ui->btnServer, &QPushButton::clicked, serversetting, &ServerSetting::show);
+
+}
+
+void FrmSetting::schRenameSlot(bool checked)
+{
+    fileConfig->setRename(checked);
+    ui->labRenameOpen->setStyleSheet(checked?OPENQSS:CLOSEQSS);
+    ui->labRenameClose->setStyleSheet(checked?CLOSEQSS:OPENQSS);
+}
+
+void FrmSetting::schAutoSetup(bool checked)
+{
+    fileConfig->setAutoSetup(checked);
+    ui->labAutoSetupOpen->setStyleSheet(checked?OPENQSS:CLOSEQSS);
+    ui->labAutoSetupClose->setStyleSheet(checked?CLOSEQSS:OPENQSS);
+}
+
+void FrmSetting::schTimeRename(bool checked)
+{
+    fileConfig->setTimeRename(checked);
+    ui->labTimeRenameOpen->setStyleSheet(checked?OPENQSS:CLOSEQSS);
+    ui->labTimeRenameClose->setStyleSheet(checked?CLOSEQSS:OPENQSS);
+}
+
+void FrmSetting::schEnableSsl(bool checked)
+{
+    fileConfig->setAutoCopy(checked);
+    ui->labEnableSslOpen->setStyleSheet(checked?OPENQSS:CLOSEQSS);
+    ui->labEnableSslClose->setStyleSheet(checked?CLOSEQSS:OPENQSS);
+
+    TCHttpService::getInstance()->setSsl(checked);
+}
+
+
+

+ 47 - 0
core_form/frmsetting/frmsetting.h

@@ -0,0 +1,47 @@
+#ifndef FRMSETTING_H
+#define FRMSETTING_H
+
+#include <QWidget>
+#include "fileconfigdecode.h"
+#include "serversetting.h"
+#include "tchttpservice.h"
+// 开机自启动
+// 域名/地址
+// 端口
+// 上传前重命名
+// 时间戳重命名
+// 上传后复制URL
+
+#define OPENQSS "QLabel{color:#409EFF;}"
+#define CLOSEQSS "QLabel{color:#FFFFFF;}"
+
+namespace Ui {
+class FrmSetting;
+}
+
+class FrmSetting : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit FrmSetting(FileConfigDecode* fileConfig, QWidget *parent = nullptr);
+    ~FrmSetting();
+
+private:
+
+    void initForm();
+    void initWidget();
+
+private slots:
+    void schRenameSlot(bool checked);
+    void schAutoSetup(bool checked);
+    void schTimeRename(bool checked);
+    void schEnableSsl(bool checked);
+
+private:
+    Ui::FrmSetting *ui;
+    FileConfigDecode* fileConfig = nullptr;
+    ServerSetting* serversetting;
+};
+
+#endif // FRMSETTING_H

+ 8 - 0
core_form/frmsetting/frmsetting.pri

@@ -0,0 +1,8 @@
+FORMS += \
+    $$PWD/frmsetting.ui
+
+HEADERS += \
+    $$PWD/frmsetting.h
+
+SOURCES += \
+    $$PWD/frmsetting.cpp

+ 364 - 0
core_form/frmsetting/frmsetting.ui

@@ -0,0 +1,364 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FrmSetting</class>
+ <widget class="QWidget" name="FrmSetting">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>731</width>
+    <height>439</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="labServer">
+       <property name="text">
+        <string>设置Server</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="btnServer">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>100</width>
+         <height>35</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>点击设置</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="Line" name="line">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QLabel" name="labAutoSetup">
+       <property name="text">
+        <string>开机自启</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QLabel" name="labAutoSetupClose">
+       <property name="text">
+        <string>关</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="SwitchButton" name="schAutoSetup" native="true">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Maximum" vsizetype="Minimum">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>200</width>
+         <height>30</height>
+        </size>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="labAutoSetupOpen">
+       <property name="text">
+        <string>开</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="Line" name="line1">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <item>
+      <widget class="QLabel" name="labRename">
+       <property name="text">
+        <string>上传重命名</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_3">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QLabel" name="labRenameClose">
+       <property name="text">
+        <string>关</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="SwitchButton" name="schRename" native="true">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>200</width>
+         <height>30</height>
+        </size>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="labRenameOpen">
+       <property name="text">
+        <string>开</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="Line" name="line2">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_4">
+     <item>
+      <widget class="QLabel" name="labTimeRename">
+       <property name="text">
+        <string>时间戳重命名</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_4">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QLabel" name="labTimeRenameClose">
+       <property name="text">
+        <string>关</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="SwitchButton" name="schTimeRename" native="true">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>200</width>
+         <height>30</height>
+        </size>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="labTimeRenameOpen">
+       <property name="text">
+        <string>开</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="Line" name="line3">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_5">
+     <item>
+      <widget class="QLabel" name="labEnableSsl">
+       <property name="text">
+        <string>开启SSL</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_5">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QLabel" name="labEnableSslClose">
+       <property name="text">
+        <string>关</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="SwitchButton" name="schEnableSsl" native="true">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>200</width>
+         <height>30</height>
+        </size>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="labEnableSslOpen">
+       <property name="text">
+        <string>开</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>SwitchButton</class>
+   <extends>QWidget</extends>
+   <header location="global">switchbutton.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>

+ 103 - 0
core_form/frmupload/frmupload.cpp

@@ -0,0 +1,103 @@
+#include "frmupload.h"
+#include "ui_frmupload.h"
+#include <QtDebug>
+#include <QImageReader>
+
+FrmUpload::FrmUpload(QWidget *parent)
+    : QWidget(parent)
+    , ui(new Ui::FrmUpload)
+{
+    ui->setupUi(this);
+    initFrom();
+    initWidget();
+}
+
+FrmUpload::~FrmUpload()
+{
+    delete ui;
+}
+
+bool FrmUpload::eventFilter(QObject *watched, QEvent *event)
+{
+    static bool mousePressed = false;
+    if (watched == ui->frmUpload) {
+        QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
+        if (mouseEvent->type() == QMouseEvent::MouseButtonPress && mouseEvent->button() == Qt::LeftButton) {
+            mousePressed = true;
+            return  true;
+        }
+        else if (mouseEvent->type() == QMouseEvent::MouseButtonRelease && mouseEvent->button() == Qt::LeftButton && mousePressed == true) {
+            QStringList fileList = QFileDialog::getOpenFileNames(this, "选择图片", "C:\\", "Files (*);;"
+                                                                                       "PNG (*.png);;"
+                                                                                       "JPG (*.jpg);;"
+                                                                                       "JPEG (*.jpeg);;"
+                                                                                       "SVG (*.svg)");
+            uploadFiles(fileList);
+            mousePressed = false;
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    return QWidget::eventFilter(watched, event);
+}
+
+void FrmUpload::dragEnterEvent(QDragEnterEvent *event)
+{
+    if (event->mimeData()->hasUrls()) {
+        event->acceptProposedAction();
+    }
+    else {
+        event->ignore();
+    }
+}
+
+void FrmUpload::dropEvent(QDropEvent *event)
+{
+    QStringList uploadList;
+    const QMimeData* mimeData = event->mimeData();
+    if (!mimeData->hasUrls()) {
+        return;
+    }
+    QList<QUrl> urlList = mimeData->urls();
+
+
+#if DEBUG
+    foreach (QUrl url, urlList) {
+        qDebug() << url.toLocalFile();
+    }
+#endif
+
+    foreach (QUrl url, urlList) {
+        QFileInfo fileInfo(url.toLocalFile());
+        if (fileInfo.isDir()) {
+            continue;
+        }
+        else {
+//            QImageReader reader(url.toLocalFile());
+//            if (!reader.imageFormat()) {
+//                uploadList << url.toLocalFile();
+//            TCHttpService::getInstance()->apiMd5(fileInfo.absoluteFilePath());
+            }
+        }
+
+}
+
+void FrmUpload::initFrom()
+{
+    ui->frmUpload->setMinimumSize(QSize(400, 200));
+}
+
+void FrmUpload::initWidget()
+{
+    ui->frmUpload->installEventFilter(this);
+    this->setAcceptDrops(true);
+//    ui->frmUpload->setAcceptDrops(true);
+}
+
+void FrmUpload::uploadFiles(QStringList fileList)
+{
+
+}

+ 42 - 0
core_form/frmupload/frmupload.h

@@ -0,0 +1,42 @@
+#ifndef FRMUPLOAD_H
+#define FRMUPLOAD_H
+
+#include <QWidget>
+#include <QMouseEvent>
+#include <QEvent>
+#include <QDropEvent>
+#include <QMoveEvent>
+#include <QFileDialog>
+#include <QMimeData>
+#include <QDragEnterEvent>
+#include <tchttpservice.h>
+
+#define DEBUG   1
+
+namespace Ui {
+class FrmUpload;
+}
+
+class FrmUpload : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit FrmUpload(QWidget *parent = nullptr);
+    ~FrmUpload();
+
+protected:
+    virtual bool eventFilter(QObject* watched, QEvent* event);
+    virtual void dragEnterEvent(QDragEnterEvent *event) override;
+    virtual void dropEvent(QDropEvent *event) override;
+
+private:
+    void initFrom();
+    void initWidget();
+    void uploadFiles(QStringList fileList);
+
+private:
+    Ui::FrmUpload *ui;
+};
+
+#endif // FRMUPLOAD_H

+ 8 - 0
core_form/frmupload/frmupload.pri

@@ -0,0 +1,8 @@
+FORMS += \
+    $$PWD/frmupload.ui
+
+HEADERS += \
+    $$PWD/frmupload.h
+
+SOURCES += \
+    $$PWD/frmupload.cpp

+ 158 - 0
core_form/frmupload/frmupload.ui

@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FrmUpload</class>
+ <widget class="QWidget" name="FrmUpload">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>953</width>
+    <height>560</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QFrame" name="frmUpload">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>800</width>
+         <height>450</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>800</width>
+         <height>450</height>
+        </size>
+       </property>
+       <property name="styleSheet">
+        <string notr="true"/>
+       </property>
+       <property name="frameShape">
+        <enum>QFrame::NoFrame</enum>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout_2">
+        <item>
+         <spacer name="verticalSpacer">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>75</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_2">
+          <item>
+           <spacer name="horizontalSpacer_2">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="QLabel" name="labPixmap">
+            <property name="text">
+             <string/>
+            </property>
+            <property name="pixmap">
+             <pixmap resource="../../image.qrc">:/qrc/image/upload_white.png</pixmap>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignCenter</set>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer_3">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <widget class="QLabel" name="labText">
+          <property name="font">
+           <font>
+            <family>Microsoft YaHei UI</family>
+            <pointsize>26</pointsize>
+           </font>
+          </property>
+          <property name="text">
+           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; color:white;&quot;&gt;将文件拖拽到此处,或&lt;/span&gt;&lt;span style=&quot; color:#407AB4;&quot;&gt;点击上传&lt;/span&gt;。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="verticalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>74</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::Fixed</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../../image.qrc"/>
+ </resources>
+ <connections/>
+</ui>

+ 48 - 0
core_form/serversetting/serversetting.cpp

@@ -0,0 +1,48 @@
+#include "serversetting.h"
+#include "ui_serversetting.h"
+
+ServerSetting::ServerSetting(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::ServerSetting)
+{
+    ui->setupUi(this);
+    initForm();
+    initWidget();
+}
+
+ServerSetting::~ServerSetting()
+{
+    delete ui;
+}
+
+void ServerSetting::initForm()
+{
+    this->setWindowFlag(Qt::FramelessWindowHint);
+    this->setWindowFlags(this->windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowMaximizeButtonHint);
+    ui->ledAddress->setPlaceholderText("example.com/ip:port");
+    ui->ledPort->setPlaceholderText("admin");
+}
+
+void ServerSetting::initWidget()
+{
+    connect(ui->btnCencel, &QPushButton::clicked, [&](){
+        this->hide();
+    });
+    connect(ui->btnOk, &QPushButton::clicked, [&](){
+        emit okClicked(ui->ledAddress->text(), ui->ledPort->text().toInt());
+        this->hide();
+    });
+}
+
+void ServerSetting::on_btnOk_clicked()
+{
+    if (ui->ledAddress->text().isEmpty() || ui->ledPort->text().isEmpty() ||
+            ui->ledPwd->text().isEmpty())
+        return;
+
+    QString address = ui->ledAddress->text();
+    QString userName = ui->ledPort->text();
+    QString password = ui->ledPwd->text();
+
+    TCHttpService::getInstance()->setConfiguration(userName, password, address);
+}

+ 33 - 0
core_form/serversetting/serversetting.h

@@ -0,0 +1,33 @@
+#ifndef SERVERSETTING_H
+#define SERVERSETTING_H
+
+#include <QWidget>
+#include "tchttpservice.h"
+
+namespace Ui {
+class ServerSetting;
+}
+
+class ServerSetting : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit ServerSetting(QWidget *parent = nullptr);
+    ~ServerSetting();
+
+signals:
+    void okClicked(QString addr, quint16 port);
+
+private slots:
+    void on_btnOk_clicked();
+
+private:
+    Ui::ServerSetting *ui;
+
+private:
+    void initForm();
+    void initWidget();
+};
+
+#endif // SERVERSETTING_H

+ 8 - 0
core_form/serversetting/serversetting.pri

@@ -0,0 +1,8 @@
+FORMS += \
+    $$PWD/serversetting.ui
+
+HEADERS += \
+    $$PWD/serversetting.h
+
+SOURCES += \
+    $$PWD/serversetting.cpp

+ 101 - 0
core_form/serversetting/serversetting.ui

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ServerSetting</class>
+ <widget class="QWidget" name="ServerSetting">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>281</width>
+    <height>188</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QFormLayout" name="formLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="labAddress">
+       <property name="text">
+        <string>Server</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="labPort">
+       <property name="text">
+        <string>Name</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="ledAddress"/>
+     </item>
+     <item row="1" column="1">
+      <widget class="QLineEdit" name="ledPort"/>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Password</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="QLineEdit" name="ledPwd"/>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="btnCencel">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>取消</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="btnOk">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="styleSheet">
+        <string notr="true"/>
+       </property>
+       <property name="text">
+        <string>确定</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 473 - 0
core_form/switchbutton/switchbutton.cpp

@@ -0,0 +1,473 @@
+#pragma execution_character_set("utf-8")
+
+#include "switchbutton.h"
+#include "qpainter.h"
+#include <QPainterPath>
+#include "qevent.h"
+#include "qtimer.h"
+#include "qdebug.h"
+
+SwitchButton::SwitchButton(QWidget *parent): QWidget(parent)
+{
+    space = 2;
+    rectRadius = 5;
+    checked = false;
+    showText = true;
+    showCircle = false;
+    animation = false;
+
+    buttonStyle	= ButtonStyle_CircleIn;
+
+    bgColorOff = QColor(111, 122, 126);
+    bgColorOn = QColor(21, 156, 119);
+
+    sliderColorOff = QColor(255, 255, 255);
+    sliderColorOn = QColor(255, 255, 255);
+
+    textColorOff = QColor(250, 250, 250);
+    textColorOn = QColor(255, 255, 255);
+
+    textOff = "关闭";
+    textOn = "开启";
+
+    step = 0;
+    startX = 0;
+    endX = 0;
+
+    timer = new QTimer(this);
+    timer->setInterval(30);
+    connect(timer, SIGNAL(timeout()), this, SLOT(updateValue()));
+}
+
+SwitchButton::~SwitchButton()
+{
+    if (timer->isActive()) {
+        timer->stop();
+    }
+}
+
+void SwitchButton::mousePressEvent(QMouseEvent *)
+{
+    checked = !checked;
+    emit checkedChanged(checked);
+
+    //每次移动的步长
+    step = width() / 7;
+
+    //状态切换改变后自动计算终点坐标
+    if (checked) {
+        if (buttonStyle == ButtonStyle_Rect) {
+            endX = width() - width() / 2;
+        } else if (buttonStyle == ButtonStyle_CircleIn) {
+            endX = width() - height();
+        } else if (buttonStyle == ButtonStyle_CircleOut) {
+            endX = width() - height();
+        }
+    } else {
+        endX = 0;
+    }
+
+    if (animation) {
+        timer->start();
+    } else {
+        startX = endX;
+        this->update();
+    }
+}
+
+void SwitchButton::resizeEvent(QResizeEvent *)
+{
+    //每次移动的步长为宽度的 50分之一
+    step = width() / 50;
+
+    //尺寸大小改变后自动设置起点坐标为终点
+    if (checked) {
+        if (buttonStyle == ButtonStyle_Rect) {
+            startX = width() - width() / 2;
+        } else if (buttonStyle == ButtonStyle_CircleIn) {
+            startX = width() - height();
+        } else if (buttonStyle == ButtonStyle_CircleOut) {
+            startX = width() - height();
+        }
+    } else {
+        startX = 0;
+    }
+
+    this->update();
+}
+
+void SwitchButton::paintEvent(QPaintEvent *)
+{
+    //绘制准备工作,启用反锯齿
+    QPainter painter(this);
+    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+
+    //绘制背景
+    drawBg(&painter);
+    //绘制滑块
+    drawSlider(&painter);
+}
+
+void SwitchButton::drawBg(QPainter *painter)
+{
+    painter->save();
+    painter->setPen(Qt::NoPen);
+
+    QColor bgColor = checked ? bgColorOn : bgColorOff;
+    if (!isEnabled()) {
+        bgColor.setAlpha(60);
+    }
+
+    painter->setBrush(bgColor);
+
+    if (buttonStyle == ButtonStyle_Rect) {
+        painter->drawRoundedRect(rect(), rectRadius, rectRadius);
+    } else if (buttonStyle == ButtonStyle_CircleIn) {
+        QRect rect(0, 0, width(), height());
+        //半径为高度的一半
+        int side = qMin(rect.width(), rect.height());
+
+        //左侧圆
+        QPainterPath path1;
+        path1.addEllipse(rect.x(), rect.y(), side, side);
+        //右侧圆
+        QPainterPath path2;
+        path2.addEllipse(rect.width() - side, rect.y(), side, side);
+        //中间矩形
+        QPainterPath path3;
+        path3.addRect(rect.x() + side / 2, rect.y(), rect.width() - side, rect.height());
+
+        QPainterPath path;
+        path = path3 + path1 + path2;
+        painter->drawPath(path);
+    } else if (buttonStyle == ButtonStyle_CircleOut) {
+        QRect rect(height() / 2, space, width() - height(), height() - space * 2);
+        painter->drawRoundedRect(rect, rectRadius, rectRadius);
+    }
+
+    if (buttonStyle == ButtonStyle_Rect || buttonStyle == ButtonStyle_CircleIn) {
+        //绘制文本和小圆,互斥
+        if (showText) {
+            int sliderWidth = qMin(width(), height()) - space * 2;
+            if (buttonStyle == ButtonStyle_Rect) {
+                sliderWidth = width() / 2 - 5;
+            } else if (buttonStyle == ButtonStyle_CircleIn) {
+                sliderWidth -= 5;
+            }
+
+            if (checked) {
+                QRect textRect(0, 0, width() - sliderWidth, height());
+                painter->setPen(textColorOn);
+                painter->drawText(textRect, Qt::AlignCenter, textOn);
+            } else {
+                QRect textRect(sliderWidth, 0, width() - sliderWidth, height());
+                painter->setPen(textColorOff);
+                painter->drawText(textRect, Qt::AlignCenter, textOff);
+            }
+        } else if (showCircle) {
+            int side = qMin(width(), height()) / 2;
+            int y = (height() - side) / 2;
+
+            if (checked) {
+                QRect circleRect(side / 2, y, side, side);
+                QPen pen(textColorOn, 2);
+                painter->setPen(pen);
+                painter->setBrush(Qt::NoBrush);
+                painter->drawEllipse(circleRect);
+            } else {
+                QRect circleRect(width() - (side * 1.5), y, side, side);
+                QPen pen(textColorOff, 2);
+                painter->setPen(pen);
+                painter->setBrush(Qt::NoBrush);
+                painter->drawEllipse(circleRect);
+            }
+        }
+    }
+
+    painter->restore();
+}
+
+void SwitchButton::drawSlider(QPainter *painter)
+{
+    painter->save();
+    painter->setPen(Qt::NoPen);
+
+    if (!checked) {
+        painter->setBrush(sliderColorOff);
+    } else {
+        painter->setBrush(sliderColorOn);
+    }
+
+    if (buttonStyle == ButtonStyle_Rect) {
+        int sliderWidth = width() / 2 - space * 2;
+        int sliderHeight = height() - space * 2;
+        QRect sliderRect(startX + space, space, sliderWidth , sliderHeight);
+        painter->drawRoundedRect(sliderRect, rectRadius, rectRadius);
+    } else if (buttonStyle == ButtonStyle_CircleIn) {
+        QRect rect(0, 0, width(), height());
+        int sliderWidth = qMin(rect.width(), rect.height()) - space * 2;
+        QRect sliderRect(startX + space, space, sliderWidth, sliderWidth);
+        painter->drawEllipse(sliderRect);
+    } else if (buttonStyle == ButtonStyle_CircleOut) {
+        int sliderWidth = this->height();
+        QRect sliderRect(startX, 0, sliderWidth, sliderWidth);
+
+        QColor color1 = (checked ? Qt::white : bgColorOff);
+        QColor color2 = (checked ? sliderColorOn : sliderColorOff);
+
+        QRadialGradient radialGradient(sliderRect.center(), sliderWidth / 2);
+        radialGradient.setColorAt(0, checked ? color1 : color2);
+        radialGradient.setColorAt(0.5, checked ? color1 : color2);
+        radialGradient.setColorAt(0.6, checked ? color2 : color1);
+        radialGradient.setColorAt(1.0, checked ? color2 : color1);
+        painter->setBrush(radialGradient);
+
+        painter->drawEllipse(sliderRect);
+    }
+
+    painter->restore();
+}
+
+void SwitchButton::change()
+{
+    mousePressEvent(NULL);
+}
+
+void SwitchButton::updateValue()
+{
+    if (checked) {
+        if (startX < endX) {
+            startX = startX + step;
+        } else {
+            startX = endX;
+            timer->stop();
+        }
+    } else {
+        if (startX > endX) {
+            startX = startX - step;
+        } else {
+            startX = endX;
+            timer->stop();
+        }
+    }
+
+    this->update();
+}
+
+int SwitchButton::getSpace() const
+{
+    return this->space;
+}
+
+int SwitchButton::getRectRadius() const
+{
+    return this->rectRadius;
+}
+
+bool SwitchButton::getChecked() const
+{
+    return this->checked;
+}
+
+bool SwitchButton::getShowText() const
+{
+    return this->showText;
+}
+
+bool SwitchButton::getShowCircle() const
+{
+    return this->showCircle;
+}
+
+bool SwitchButton::getAnimation() const
+{
+    return this->animation;
+}
+
+SwitchButton::ButtonStyle SwitchButton::getButtonStyle() const
+{
+    return this->buttonStyle;
+}
+
+QColor SwitchButton::getBgColorOff() const
+{
+    return bgColorOff;
+}
+
+QColor SwitchButton::getBgColorOn() const
+{
+    return this->bgColorOn;
+}
+
+QColor SwitchButton::getSliderColorOff() const
+{
+    return this->sliderColorOff;
+}
+
+QColor SwitchButton::getSliderColorOn() const
+{
+    return this->sliderColorOn;
+}
+
+QColor SwitchButton::getTextColorOff() const
+{
+    return this->textColorOff;
+}
+
+QColor SwitchButton::getTextColorOn() const
+{
+    return this->textColorOn;
+}
+
+QString SwitchButton::getTextOff() const
+{
+    return this->textOff;
+}
+
+QString SwitchButton::getTextOn() const
+{
+    return this->textOn;
+}
+
+QSize SwitchButton::sizeHint() const
+{
+    return QSize(70, 30);
+}
+
+QSize SwitchButton::minimumSizeHint() const
+{
+    return QSize(10, 5);
+}
+
+void SwitchButton::setSpace(int space)
+{
+    if (this->space != space) {
+        this->space = space;
+        this->update();
+    }
+}
+
+void SwitchButton::setRectRadius(int rectRadius)
+{
+    if (this->rectRadius != rectRadius) {
+        this->rectRadius = rectRadius;
+        this->update();
+    }
+}
+
+void SwitchButton::setChecked(bool checked)
+{
+    //如果刚刚初始化完成的属性改变则延时处理
+    if (this->checked != checked) {
+        if (step == 0) {
+            QTimer::singleShot(10, this, SLOT(change()));
+        } else {
+            mousePressEvent(NULL);
+        }
+    }
+}
+
+void SwitchButton::setShowText(bool showText)
+{
+    if (this->showText != showText) {
+        this->showText = showText;
+        this->update();
+    }
+}
+
+void SwitchButton::setShowCircle(bool showCircle)
+{
+    if (this->showCircle != showCircle) {
+        this->showCircle = showCircle;
+        this->update();
+    }
+}
+
+void SwitchButton::setAnimation(bool animation)
+{
+    if (this->animation != animation) {
+        this->animation = animation;
+        this->update();
+    }
+}
+
+void SwitchButton::setButtonStyle(const SwitchButton::ButtonStyle &buttonStyle)
+{
+    if (this->buttonStyle != buttonStyle) {
+        this->buttonStyle = buttonStyle;
+        this->update();
+    }
+}
+
+void SwitchButton::setBgColorOff(const QColor &bgColorOff)
+{
+    if (this->bgColorOff != bgColorOff) {
+        this->bgColorOff = bgColorOff;
+        this->update();
+    }
+}
+
+void SwitchButton::setBgColorOn(const QColor &bgColorOn)
+{
+    if (this->bgColorOn != bgColorOn) {
+        this->bgColorOn = bgColorOn;
+        this->update();
+    }
+}
+
+void SwitchButton::setSliderColorOff(const QColor &sliderColorOff)
+{
+    if (this->sliderColorOff != sliderColorOff) {
+        this->sliderColorOff = sliderColorOff;
+        this->update();
+    }
+}
+
+void SwitchButton::setSliderColorOn(const QColor &sliderColorOn)
+{
+    if (this->sliderColorOn != sliderColorOn) {
+        this->sliderColorOn = sliderColorOn;
+        this->update();
+    }
+}
+
+void SwitchButton::setTextColorOff(const QColor &textColorOff)
+{
+    if (this->textColorOff != textColorOff) {
+        this->textColorOff = textColorOff;
+        this->update();
+    }
+}
+
+void SwitchButton::setTextColorOn(const QColor &textColorOn)
+{
+    if (this->textColorOn != textColorOn) {
+        this->textColorOn = textColorOn;
+        this->update();
+    }
+}
+
+void SwitchButton::enableText(bool enable)
+{
+    if (!enable) {
+        this->textOn = "";
+        this->textOff = "";
+        this->update();
+    }
+}
+
+void SwitchButton::setTextOff(const QString &textOff)
+{
+    if (this->textOff != textOff) {
+        this->textOff = textOff;
+        this->update();
+    }
+}
+
+void SwitchButton::setTextOn(const QString &textOn)
+{
+    if (this->textOn != textOn) {
+        this->textOn = textOn;
+        this->update();
+    }
+}

+ 159 - 0
core_form/switchbutton/switchbutton.h

@@ -0,0 +1,159 @@
+#ifndef SWITCHBUTTON_H
+#define SWITCHBUTTON_H
+
+/**
+ * 开关按钮控件 作者:feiyangqingyun(QQ:517216493) 2016-11-6
+ * 1:可设置开关按钮的样式 圆角矩形/内圆形/外圆形
+ * 2:可设置选中和未选中时的背景颜色
+ * 3:可设置选中和未选中时的滑块颜色
+ * 4:可设置显示的文本
+ * 5:可设置滑块离背景的间隔
+ * 6:可设置圆角角度
+ * 7:可设置是否显示动画过渡效果
+ */
+
+#include <QWidget>
+#include <QPainterPath>
+
+#ifdef quc
+#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
+#include <QtDesigner/QDesignerExportWidget>
+#else
+#include <QtUiPlugin/QDesignerExportWidget>
+#endif
+
+class QDESIGNER_WIDGET_EXPORT SwitchButton : public QWidget
+#else
+class SwitchButton : public QWidget
+#endif
+
+{
+    Q_OBJECT
+    Q_ENUMS(ButtonStyle)
+
+    Q_PROPERTY(int space READ getSpace WRITE setSpace)
+    Q_PROPERTY(int rectRadius READ getRectRadius WRITE setRectRadius)
+    Q_PROPERTY(bool checked READ getChecked WRITE setChecked)
+    Q_PROPERTY(bool showText READ getShowText WRITE setShowText)
+    Q_PROPERTY(bool showCircle READ getShowCircle WRITE setShowCircle)
+    Q_PROPERTY(bool animation READ getAnimation WRITE setAnimation)
+    Q_PROPERTY(ButtonStyle buttonStyle READ getButtonStyle WRITE setButtonStyle)
+
+    Q_PROPERTY(QColor bgColorOff READ getBgColorOff WRITE setBgColorOff)
+    Q_PROPERTY(QColor bgColorOn READ getBgColorOn WRITE setBgColorOn)
+    Q_PROPERTY(QColor sliderColorOff READ getSliderColorOff WRITE setSliderColorOff)
+    Q_PROPERTY(QColor sliderColorOn READ getSliderColorOn WRITE setSliderColorOn)
+    Q_PROPERTY(QColor textColorOff READ getTextColorOff WRITE setTextColorOff)
+    Q_PROPERTY(QColor textColorOn READ getTextColorOn WRITE setTextColorOn)
+
+    Q_PROPERTY(QString textOff READ getTextOff WRITE setTextOff)
+    Q_PROPERTY(QString textOn READ getTextOn WRITE setTextOn)
+
+public:
+    enum ButtonStyle {
+        ButtonStyle_Rect = 0,       //圆角矩形
+        ButtonStyle_CircleIn = 1,   //内圆形
+        ButtonStyle_CircleOut = 2   //外圆形
+    };
+
+    SwitchButton(QWidget *parent = 0);
+    ~SwitchButton();
+
+protected:
+    void mousePressEvent(QMouseEvent *);
+    void resizeEvent(QResizeEvent *);
+    void paintEvent(QPaintEvent *);
+    void drawBg(QPainter *painter);
+    void drawSlider(QPainter *painter);
+
+private:
+    int space;                      //滑块离背景间隔
+    int rectRadius;                 //圆角角度
+    bool checked;                   //是否选中
+    bool showText;                  //显示文字
+    bool showCircle;                //显示小圆
+    bool animation;                 //动画过渡
+
+    ButtonStyle buttonStyle;        //开关按钮样式
+
+    QColor bgColorOff;              //关闭时背景颜色
+    QColor bgColorOn;               //打开时背景颜色
+    QColor sliderColorOff;          //关闭时滑块颜色
+    QColor sliderColorOn;           //打开时滑块颜色
+    QColor textColorOff;            //关闭时文字颜色
+    QColor textColorOn;             //打开时文字颜色
+
+    QString textOff;                //关闭时显示的文字
+    QString textOn;                 //打开时显示的文字
+
+    int step;                       //每次移动的步长
+    int startX;                     //滑块开始X轴坐标
+    int endX;                       //滑块结束X轴坐标
+    QTimer *timer;                  //定时器绘制
+
+private slots:
+    void change();
+    void updateValue();
+
+public:
+    int getSpace()                  const;
+    int getRectRadius()             const;
+    bool getChecked()               const;
+    bool getShowText()              const;
+    bool getShowCircle()            const;
+    bool getAnimation()             const;
+
+    ButtonStyle getButtonStyle()    const;
+
+    QColor getBgColorOff()          const;
+    QColor getBgColorOn()           const;
+    QColor getSliderColorOff()      const;
+    QColor getSliderColorOn()       const;
+    QColor getTextColorOff()        const;
+    QColor getTextColorOn()         const;
+
+    QString getTextOff()            const;
+    QString getTextOn()             const;
+
+    QSize sizeHint()                const;
+    QSize minimumSizeHint()         const;
+
+public Q_SLOTS:
+    //设置间隔
+    void setSpace(int space);
+    //设置圆角角度
+    void setRectRadius(int rectRadius);
+    //设置是否选中
+    void setChecked(bool checked);
+    //设置是否显示文字
+    void setShowText(bool showText);
+    //设置是否显示小圆
+    void setShowCircle(bool showCircle);
+    //设置是否动画过渡
+    void setAnimation(bool animation);
+
+    //设置风格样式
+    void setButtonStyle(const ButtonStyle &buttonStyle);
+
+    //设置背景颜色
+    void setBgColorOff(const QColor &bgColorOff);
+    void setBgColorOn(const QColor &bgColorOn);
+
+    //设置滑块颜色
+    void setSliderColorOff(const QColor &sliderColorOff);
+    void setSliderColorOn(const QColor &sliderColorOn);
+
+    //设置文字颜色
+    void setTextColorOff(const QColor &textColorOff);
+    void setTextColorOn(const QColor &textColorOn);
+    void enableText(bool enable);
+
+    //设置文字
+    void setTextOff(const QString &textOff);
+    void setTextOn(const QString &textOn);
+
+Q_SIGNALS:
+    void checkedChanged(bool checked);
+};
+
+#endif // SWITCHBUTTON_H

+ 5 - 0
core_form/switchbutton/switchbutton.pri

@@ -0,0 +1,5 @@
+HEADERS += \
+    $$PWD/switchbutton.h
+
+SOURCES += \
+    $$PWD/switchbutton.cpp

+ 6 - 0
core_support/core_support.pri

@@ -0,0 +1,6 @@
+INCLUDEPATH += $$PWD
+INCLUDEPATH += $$PWD/fileconfigdecode
+include($$PWD/fileconfigdecode/fileconfigdecode.pri)
+
+INCLUDEPATH += $$PWD/tchttpservice
+include($$PWD/tchttpservice/tchttpservice.pri)

+ 149 - 0
core_support/fileconfigdecode/fileconfigdecode.cpp

@@ -0,0 +1,149 @@
+#include "fileconfigdecode.h"
+#include <QDebug>
+
+FileConfigDecode::FileConfigDecode()
+{
+    initFile();
+    qDebug() << "read:" << autoSetup << rename << timeRename << autoCopy;
+}
+
+FileConfigDecode::~FileConfigDecode()
+{
+    updateFile();
+//    qDebug() << "write:" << autoSetup << rename << timeRename << autoCopy;
+}
+
+QString FileConfigDecode::getAddress()
+{
+    return this->address;
+}
+
+quint16 FileConfigDecode::getPort()
+{
+    return port;
+}
+
+bool FileConfigDecode::getAutoSetup()
+{
+    return autoSetup;
+}
+
+bool FileConfigDecode::getRename()
+{
+    return rename;
+}
+
+bool FileConfigDecode::getTimeRename()
+{
+    return timeRename;
+}
+
+bool FileConfigDecode::getAutoCopy()
+{
+    return autoCopy;
+}
+
+void FileConfigDecode::setAddress(QString value)
+{
+    this->address = value;
+//    updateFile();
+}
+
+void FileConfigDecode::setPort(quint16 value)
+{
+    this->port = value;
+//    updateFile();
+}
+
+void FileConfigDecode::setAutoSetup(bool value)
+{
+    this->autoSetup = value;
+//    updateFile();
+}
+
+void FileConfigDecode::setRename(bool value)
+{
+    this->rename = value;
+//    updateFile();
+}
+
+void FileConfigDecode::setTimeRename(bool value)
+{
+    this->timeRename = value;
+//    updateFile();
+}
+
+void FileConfigDecode::setAutoCopy(bool value)
+{
+    this->autoCopy = value;
+//    updateFile();
+}
+
+void FileConfigDecode::fileWrite(QString path, QString address, quint16 port, bool autosetup, bool rename, bool timerename, bool autocopy)
+{
+    QSettings* config = new QSettings(path, QSettings::IniFormat);
+    config->setIniCodec(QTextCodec::codecForName("utf-8"));
+    QString section = QString("config");
+    config->beginGroup(section);
+    config->setValue("address", address);
+    config->setValue("port", port);
+    config->setValue("autosetup", autosetup);
+    config->setValue("rename", rename);
+    config->setValue("timerename", timerename);
+    config->setValue("autocopy", autocopy);
+    config->endGroup();
+    delete config;
+}
+
+void FileConfigDecode::initFile()
+{
+    QString addDataPath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
+    QString addFilePath = addDataPath + "config.ini";
+    qDebug() << addFilePath;
+    QFile file(addFilePath);
+    if (file.exists()) {
+        QSettings* config = new QSettings(addFilePath, QSettings::IniFormat);
+        config->setIniCodec(QTextCodec::codecForName("utf-8"));
+        QString section = "config/";
+
+        this->address = config->value(section + "address").toString();
+        this->port = config->value(section + "port").toUInt();
+        this->autoSetup = config->value(section + "autosetup").toBool();
+        this->rename = config->value(section + "rename").toBool();
+        this->timeRename = config->value(section + "timerename").toBool();
+        this->autoCopy = config->value(section + "autocopy").toBool();
+
+        checkConfig();
+
+        this->firstCreate = false;
+    }
+    else {
+        this->firstCreate = true;
+
+        this->address = "127.0.0.1";
+        this->port = 0;
+        this->autoSetup = false;
+        this->rename = false;
+        this->timeRename = false;
+        this->autoCopy = false;
+
+        fileWrite(addFilePath, address, port, autoSetup, rename, timeRename, autoCopy);
+    }
+}
+
+void FileConfigDecode::checkConfig()
+{
+    if (address.isEmpty()) {
+        address = "127.0.0.1";
+    }
+}
+
+void FileConfigDecode::updateFile()
+{
+    QString addDataPath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
+    QString addFilePath = addDataPath + "config.ini";
+
+    qDebug() << "write" << autoSetup << rename << timeRename << autoCopy;
+    fileWrite(addFilePath, address, port, autoSetup, rename, timeRename, autoCopy);
+}
+

+ 51 - 0
core_support/fileconfigdecode/fileconfigdecode.h

@@ -0,0 +1,51 @@
+#ifndef FILECONFIGDECODE_H
+#define FILECONFIGDECODE_H
+
+#include <QObject>
+#include <QStandardPaths>
+#include <QFile>
+#include <QSettings>
+#include <QFileInfo>
+#include <QTextCodec>
+
+class FileConfigDecode
+{
+public:
+    FileConfigDecode();
+    ~FileConfigDecode();
+
+    QString getAddress();
+    quint16 getPort();
+    bool getAutoSetup();
+    bool getRename();
+    bool getTimeRename();
+    bool getAutoCopy();
+
+    void setAddress(QString value);
+    void setPort(quint16 value);
+    void setAutoSetup(bool value);
+    void setRename(bool value);
+    void setTimeRename(bool value);
+    void setAutoCopy(bool value);
+
+private:
+    QString address;
+    quint16 port;
+    bool autoSetup;
+    bool rename;
+    bool timeRename;
+    bool autoCopy;
+
+    bool firstCreate;
+
+    void fileWrite(QString path, QString address, quint16 port, bool autosetup, bool rename, bool timerename, bool autocopy);
+
+private:
+    void initFile();
+    void checkConfig();
+    void updateFile();
+//    void initForm();
+
+};
+
+#endif // FILECONFIGDECODE_H

+ 5 - 0
core_support/fileconfigdecode/fileconfigdecode.pri

@@ -0,0 +1,5 @@
+HEADERS += \
+    $$PWD/fileconfigdecode.h
+
+SOURCES += \
+    $$PWD/fileconfigdecode.cpp

+ 351 - 0
core_support/tchttpservice/tchttpservice.cpp

@@ -0,0 +1,351 @@
+#include "tchttpservice.h"
+QScopedPointer<TCHttpService> TCHttpService::m_instance;
+
+TCHttpService *TCHttpService::getInstance()
+{
+    if (m_instance.isNull()) {
+        m_instance.reset(new TCHttpService);
+    }
+
+    return m_instance.data();
+}
+
+void TCHttpService::apiLogin()
+{
+    QByteArray pwdMd5 = QCryptographicHash::hash(m_firstPwd.toUtf8(), QCryptographicHash::Md5);
+    QString md5Hex = pwdMd5.toHex();
+
+    QString urlStr;
+//    if (m_enableSsl)
+        urlStr = "https://" + m_domain + "/api/login";
+//    else
+//        urlStr = "http://" + m_domain + "/api/login";
+
+    QUrl url(urlStr);
+    QJsonObject jsonObj;
+    jsonObj["user"]="test1";
+    jsonObj["pwd"]=md5Hex;
+    QJsonDocument jsonDoc(jsonObj);
+    QByteArray jsonData = jsonDoc.toJson();
+    QMap<QString, QString> headers;
+    headers.insert("Content-Type", "application/json");
+
+    QNetworkReply* reply = nullptr;
+//    qDebug() <<url;
+//    QNetworkRequest request(url);
+//    reply = m_manager.post(request, jsonData);
+
+//        QObject::connect(reply, &QNetworkReply::finished, [this, reply]() {
+
+//        emit requestFinished(reply);
+//    });
+    Post(url, headers, {}, jsonData, 1);
+}
+
+void TCHttpService::apiMyfileCount()
+{
+    QString urlStr;
+    if (m_enableSsl)
+        urlStr = "https://" + m_domain + "/api/myfiles";
+    else
+        urlStr = "http://" + m_domain + "/api/myfiles";
+
+    QMap<QString, QString> headers;
+    headers.insert("Content-Type", "application/json");
+    QString bodyStr = QString("\"%1\":\"%2\",\"%3\":\"%4\"").arg("token").arg(m_token).arg("user").arg(m_userName);
+    QMap<QString, QString> params;
+    params.insert("cmd", "count");
+//    QNetworkReply* reply = Post(urlStr, headers, params, bodyStr.toUtf8());
+
+//    QObject::connect(reply, &QNetworkReply::finished, [this, reply]{
+
+//        QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
+//        QJsonObject jsonObj = jsonDoc.object();
+
+//        int code = jsonObj["code"].toInt();
+
+//        if (code == 0) {
+//            int total = jsonObj["total"].toInt();
+//            this->m_total = total;
+//        }
+
+//        reply->deleteLater();
+//    });
+
+}
+
+void TCHttpService::apiMyfileNormal()
+{
+    QString urlStr;
+    if (m_enableSsl)
+        urlStr = "https://" + m_domain + "/api/myfiles";
+    else
+        urlStr = "http://" + m_domain + "/api/myfiles";
+
+    QMap<QString, QString> headers;
+    headers.insert("Content-Type", "application/json");
+
+    QMap<QString, QString> params;
+    params.insert("cmd", "normal");
+    QString bodyStr = QString("\"%1\":\"%2\",\"%3\":\"%4\",\"%5\":\"%6\",\"%7\":\"%8\"").arg("token").arg(m_token).
+            arg("user").arg(m_userName).arg("count").arg(m_total).arg("start").arg(0);
+//    QNetworkReply* reply = Post(QUrl(urlStr), headers, params, bodyStr.toUtf8());
+
+//    QObject::connect(reply, &QNetworkReply::finished, [this, reply]{
+//       QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
+//       QJsonObject jsonObj = jsonDoc.object();
+
+//       int code = jsonObj["code"].toInt();
+//       if (code == 0) {
+//           int count = jsonObj["count"].toInt();
+//           if (count != 0) {
+//               QJsonArray array = jsonObj["files"].toArray();
+//               for (const QJsonValue& value : array) {
+//                   QJsonObject item = value.toObject();
+//                   updateFileMap(item);
+//               }
+//           }
+//       }
+
+//       reply->deleteLater();
+//    });
+}
+
+void TCHttpService::apiMd5(const QString& filePath)
+{
+    QFile file(filePath);
+    if (!file.open(QIODevice::ReadOnly)) {
+        return;
+    }
+
+    QByteArray fileMd5;
+    QCryptographicHash hash(QCryptographicHash::Md5);
+    if (hash.addData(&file)) {
+         fileMd5 = hash.result().toHex();
+    }
+    else
+        return;
+
+    QString urlStr;
+    if (m_enableSsl)
+        urlStr = "https://" + m_domain + "/api/md5";
+    else
+        urlStr = "http://" + m_domain + "/api/md5";
+    QMap<QString, QString> headers;
+    headers.insert("Content-Type", "application/json");
+    QString md5Str = QString::fromUtf8(fileMd5);
+    QString bodyStr = QString("\"%1\":\"%2\",\"%3\":\"%4\",\"%5\":\"%6\",\"%7\":\"%8\"").arg("token").arg(m_token).
+            arg("md5").arg(md5Str).arg("filename").arg(QFileInfo(file).fileName()).arg("user").arg(m_userName);
+    file.close();
+//    QNetworkReply* reply = Post(urlStr, headers, {}, bodyStr.toUtf8());
+
+//    QObject::connect(reply, &QNetworkReply::finished, [this, reply, filePath, md5Str]{
+//        QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
+//        QJsonObject jsonObj = jsonDoc.object();
+//        int code = jsonObj["code"].toInt();
+//        switch (code) {
+//        case 0:
+//            break;
+//        case 1:
+//            apiUpload(filePath, md5Str);
+//            break;
+//        }
+//    });
+}
+
+void TCHttpService::apiUpload(const QString &filePath, const QString &md5Str)
+{
+    QString urlStr;
+    if (m_enableSsl)
+        urlStr = "https://" + m_domain + "/api/upload";
+    else
+        urlStr = "http://" + m_domain + "/api/upload";
+
+    QFile file(filePath);
+    QFileInfo info(file);
+
+    QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
+    QHttpPart filePart;
+    QString contentTypeStrFile = QString("form-data; name=\"file\"; filename=\"%1\"").arg(info.fileName());
+    filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
+                       QVariant(contentTypeStrFile));
+    filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
+    if (!file.open(QIODevice::ReadOnly)) {
+        return;
+    }
+
+    filePart.setBodyDevice(&file);
+    file.setParent(multiPart);
+    multiPart->append(filePart);
+
+
+    QHttpPart userPart;
+    QString contentTypeStrUser = QString("form-data; name=\"user\"");
+    userPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(contentTypeStrUser));
+    userPart.setBody(m_userName.toUtf8());
+    multiPart->append(userPart);
+
+    QHttpPart md5Part;
+    QString contentTypeStrMd5 = QString("form-data; name=\"md5\"");
+    md5Part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentTypeStrMd5));
+    md5Part.setBody(md5Str.toUtf8());
+    multiPart->append(md5Part);
+
+    QHttpPart sizePart;
+    QString contentTypeStrSize = QString("form-data; name=\"size\"");
+    sizePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentTypeStrSize));
+    sizePart.setBody(QString::number(info.size()).toUtf8());
+    multiPart->append(sizePart);
+
+    QUrl url(urlStr);
+    QNetworkRequest request(url);
+
+    QNetworkReply* reply = m_manager.post(request, multiPart);
+    multiPart->setParent(reply);
+
+    QObject::connect(reply, &QNetworkReply::finished, [this, reply]{
+        QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
+        QJsonObject jsonObj = jsonDoc.object();
+
+        int code = jsonObj["code"].toInt();
+        if (code == 0) {
+            emit signal_uploadSuc();
+        }
+        reply->deleteLater();
+    });
+
+}
+
+void TCHttpService::apiSharePicShare(const QString &fileName, const QString &md5)
+{
+
+    QString urlStr;
+    if (m_enableSsl)
+        urlStr = "https://" + m_domain + "/api/sharepic";
+    else
+        urlStr = "http://" + m_domain + "/api/sharepic";
+
+    QMap<QString, QString> headers;
+    QMap<QString, QString> body;
+    QMap<QString, QString> params;
+
+    headers.insert("Content-Type", "application/json");
+
+    QString bodyStr = QString("\"%1\":\"%2\",\"%3\":\"%4\",\"%5\":\"%6\",\"%7\":\"%8\"").arg("token").arg(m_token).
+            arg("user").arg(m_userName).arg("md5").arg(md5).arg("filename").arg(fileName);
+
+    params.insert("cmd", "share");
+
+//    QNetworkReply* reply = Post(QUrl(urlStr), headers, params, bodyStr.toUtf8());
+
+//    QObject::connect(reply, &QNetworkReply::finished, [this, reply]{
+//        QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
+//        QJsonObject jsonObj = jsonDoc.object();
+
+//        int code = jsonObj["code"].toInt();
+//        if (code == 0) {
+//            emit signal_shareSuc();
+//        }
+//        reply->deleteLater();
+//    });
+}
+
+void TCHttpService::setConfiguration(QString userName, QString firstPwd, QString domain)
+{
+    qDebug() << "setConfiguration";
+    this->m_domain = domain;
+    this->m_userName = userName;
+    this->m_firstPwd = firstPwd;
+    connect(this, &TCHttpService::requestFinished, [](QNetworkReply* reply){
+        qDebug() << "readall";
+        qDebug() <<reply->readAll();
+        reply->deleteLater();
+    });
+    apiLogin();
+}
+
+void TCHttpService::setSsl(bool enable)
+{
+    qDebug() << "setSsl:" <<enable;
+    this->m_enableSsl = enable;
+}
+
+QNetworkReply *TCHttpService::Get(const QUrl &url, const QMap<QString, QString> headers, const QMap<QString, QString> params)
+{
+    QUrlQuery query;
+    for (auto ite = params.constBegin(); ite != params.constEnd(); ite++) {
+        query.addQueryItem(ite.key(), ite.value());
+    }
+
+    QUrl requestUrl = url;
+    requestUrl.setQuery(query);
+
+    QNetworkRequest request(requestUrl);
+
+    for (auto ite = headers.constBegin(); ite != headers.constEnd(); ite++) {
+        request.setRawHeader(ite.key().toUtf8(), ite.value().toUtf8());
+    }
+
+    QNetworkReply* reply = m_manager.get(request);
+
+    return reply;
+}
+
+QNetworkReply *TCHttpService::Post(const QUrl &url, const QMap<QString, QString> headers, const QMap<QString, QString> params, const QByteArray body)
+{
+
+}
+
+QByteArray TCHttpService::Post(QUrl url, QMap<QString, QString> headers, QMap<QString, QString> params, QByteArray body, int i)
+{
+    QUrlQuery query;
+    for (auto ite = params.constBegin(); ite != params.constEnd(); ite++) {
+        query.addQueryItem(ite.key(), ite.value());
+    }
+
+    QUrl requestUrl = url;
+    requestUrl.setQuery(query);
+    qDebug() << requestUrl;
+    QNetworkRequest request(url);
+
+//    for (auto ite = headers.constBegin(); ite != headers.constEnd(); ite++) {
+//        request.setRawHeader(ite.key().toUtf8(), ite.value().toUtf8());
+//    }
+    qDebug() << 1;
+    QJsonObject jsonObj;
+    jsonObj["user"]="test1";
+    jsonObj["pwd"]="e10adc3949ba59abbe56e057f20f883e";
+    QJsonDocument jsonDoc(jsonObj);
+    QByteArray jsonData = jsonDoc.toJson();
+    qDebug() << 2;
+    QNetworkReply* reply = nullptr;
+    qDebug() << 3;
+    reply = m_manager.post(request, jsonData);
+    qDebug() << 4;
+    QObject::connect(reply, &QNetworkReply::finished, [this, reply](){
+//        QByteArray respData = reply->readAll();
+//        qDebug() <<respData;
+//        return respData;
+//        reply->deleteLater();
+        qDebug() << "emit requestFinished";
+//        emit requestFinished(reply);
+    });
+
+}
+
+void TCHttpService::updateFileMap(QJsonObject jsonObj)
+{
+    QString fileMD5 = jsonObj["md5"].toString();
+    QString fileUrl = jsonObj["http"].toString();
+
+    QMap<QString, QString>::iterator ite = m_fileMap.begin();
+    if (ite != m_fileMap.end())
+        return;
+
+    m_fileMap.insert(fileMD5, fileUrl);
+}
+
+TCHttpService::TCHttpService(QObject *parent) : QObject(parent)
+{
+
+}

+ 68 - 0
core_support/tchttpservice/tchttpservice.h

@@ -0,0 +1,68 @@
+#ifndef TCHTTPSERVICE_H
+#define TCHTTPSERVICE_H
+
+#include <QObject>
+#include <QNetworkAccessManager>
+#include <QUrlQuery>
+#include <QCryptographicHash>
+#include <QNetworkReply>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QFile>
+#include <QFileInfo>
+#include <QHttpMultiPart>
+#include <QHttpPart>
+
+class TCHttpService : public QObject
+{
+    Q_OBJECT
+public:
+    static TCHttpService* getInstance();
+
+    void apiLogin();
+    void apiMyfileCount();
+    void apiMyfileNormal();
+    void apiMd5(const QString& filePath);
+    void apiUpload(const QString& filePath, const QString& md5);
+    void apiSharePicShare(const QString& fileName, const QString& md5);
+    void setConfiguration(QString userName, QString firstPwd, QString domain);
+    void setSsl(bool enable);
+
+private:
+
+    QNetworkReply* Get(const QUrl& url, const QMap<QString, QString> headers = {},
+                       const QMap<QString, QString> params = {});
+    QNetworkReply* Post(const QUrl& url, const QMap<QString, QString> headers = {},
+                        const QMap<QString, QString> params = {}, const QByteArray body =QByteArray());
+
+    QByteArray Post(QUrl url, QMap<QString, QString> headers = {},
+                        QMap<QString, QString> params = {}, QByteArray body =QByteArray(), int i = 1);
+    void updateFileMap(QJsonObject jsonObj);
+signals:
+    void signal_loginSuc();
+    void signal_uploadSuc();
+    void signal_shareSuc();
+
+    void requestFinished(QNetworkReply* reply);
+private:
+    explicit TCHttpService(QObject *parent = nullptr);
+
+    static QScopedPointer<TCHttpService> m_instance;
+
+    QNetworkAccessManager m_manager;
+
+    QString m_token;
+    QString m_domain;
+    QString m_firstPwd;
+    QString m_userName;
+    QMap<QString, QString> m_fileMap;
+    int m_total;
+    bool m_enableSsl = true;
+
+signals:
+
+};
+
+#endif // TCHTTPSERVICE_H

+ 5 - 0
core_support/tchttpservice/tchttpservice.pri

@@ -0,0 +1,5 @@
+HEADERS += \
+    $$PWD/tchttpservice.h
+
+SOURCES += \
+    $$PWD/tchttpservice.cpp

+ 5 - 0
core_ui/core_ui.pri

@@ -0,0 +1,5 @@
+SOURCES += \
+    $$PWD/iconhelper.cpp
+
+HEADERS += \
+    $$PWD/iconhelper.h

+ 377 - 0
core_ui/iconhelper.cpp

@@ -0,0 +1,377 @@
+#include "iconhelper.h"
+
+IconHelper *IconHelper::iconFontAliBaBa = 0;
+IconHelper *IconHelper::iconFontAwesome = 0;
+IconHelper *IconHelper::iconFontAwesome6 = 0;
+IconHelper *IconHelper::iconFontWeather = 0;
+int IconHelper::iconFontIndex = -1;
+
+void IconHelper::initFont()
+{
+    static bool isInit = false;
+    if (!isInit) {
+        isInit = true;
+        if (iconFontAliBaBa == 0) {
+            iconFontAliBaBa = new IconHelper(":/qrc/ttf/iconfont.ttf", "iconfont");
+        }
+        if (iconFontAwesome == 0) {
+            iconFontAwesome = new IconHelper(":/qrc/ttf/fontawesome-webfont.ttf", "FontAwesome");
+        }
+        if (iconFontAwesome6 == 0) {
+            iconFontAwesome6 = new IconHelper(":/qrc/ttf/fa-regular-400.ttf", "Font Awesome 6 Pro Regular");
+        }
+        if (iconFontWeather == 0) {
+            iconFontWeather = new IconHelper(":/qrc/ttf/pe-icon-set-weather.ttf", "pe-icon-set-weather");
+        }
+    }
+}
+
+void IconHelper::setIconFontIndex(int index)
+{
+    iconFontIndex = index;
+}
+
+QFont IconHelper::getIconFontAliBaBa()
+{
+    initFont();
+    return iconFontAliBaBa->getIconFont();
+}
+
+QFont IconHelper::getIconFontAwesome()
+{
+    initFont();
+    return iconFontAwesome->getIconFont();
+}
+
+QFont IconHelper::getIconFontAwesome6()
+{
+    initFont();
+    return iconFontAwesome6->getIconFont();
+}
+
+QFont IconHelper::getIconFontWeather()
+{
+    initFont();
+    return iconFontWeather->getIconFont();
+}
+
+IconHelper *IconHelper::getIconHelper(int icon)
+{
+    initFont();
+
+    //指定了字体索引则取对应索引的字体类
+    //没指定则自动根据不同的字体的值选择对应的类
+    //由于部分值范围冲突所以可以指定索引来取
+    //fontawesome   0xf000-0xf2e0
+    //fontawesome6  0xe000-0xe33d 0xf000-0xf8ff
+    //iconfont      0xe501-0xe793 0xe8d5-0xea5d 0xeb00-0xec00
+    //weather       0xe900-0xe9cf
+
+    IconHelper *iconHelper = iconFontAwesome;
+    if (iconFontIndex < 0) {
+        if ((icon >= 0xe501 && icon <= 0xe793) || (icon >= 0xe8d5 && icon <= 0xea5d) || (icon >= 0xeb00 && icon <= 0xec00)) {
+            iconHelper = iconFontAliBaBa;
+        }
+    } else if (iconFontIndex == 0) {
+        iconHelper = iconFontAliBaBa;
+    } else if (iconFontIndex == 1) {
+        iconHelper = iconFontAwesome;
+    } else if (iconFontIndex == 2) {
+        iconHelper = iconFontAwesome6;
+    } else if (iconFontIndex == 3) {
+        iconHelper = iconFontWeather;
+    }
+
+    return iconHelper;
+}
+
+void IconHelper::setIcon(QLabel *lab, int icon, quint32 size)
+{
+    getIconHelper(icon)->setIcon1(lab, icon, size);
+}
+
+void IconHelper::setIcon(QAbstractButton *btn, int icon, quint32 size)
+{
+    getIconHelper(icon)->setIcon1(btn, icon, size);
+}
+
+void IconHelper::setPixmap(QAbstractButton *btn, const QColor &color, int icon, quint32 size,
+                           quint32 width, quint32 height, int flags)
+{
+    getIconHelper(icon)->setPixmap1(btn, color, icon, size, width, height, flags);
+}
+
+QPixmap IconHelper::getPixmap(const QColor &color, int icon, quint32 size,
+                              quint32 width, quint32 height, int flags)
+{
+    return getIconHelper(icon)->getPixmap1(color, icon, size, width, height, flags);
+}
+
+void IconHelper::setStyle(QWidget *widget, QList<QPushButton *> btns,
+                          QList<int> icons, const IconHelper::StyleColor &styleColor)
+{
+    int icon = icons.first();
+    getIconHelper(icon)->setStyle1(widget, btns, icons, styleColor);
+}
+
+void IconHelper::setStyle(QWidget *widget, QList<QToolButton *> btns,
+                          QList<int> icons, const IconHelper::StyleColor &styleColor)
+{
+    int icon = icons.first();
+    getIconHelper(icon)->setStyle1(widget, btns, icons, styleColor);
+}
+
+void IconHelper::setStyle(QWidget *widget, QList<QAbstractButton *> btns,
+                          QList<int> icons, const IconHelper::StyleColor &styleColor)
+{
+    int icon = icons.first();
+    getIconHelper(icon)->setStyle1(widget, btns, icons, styleColor);
+}
+
+
+IconHelper::IconHelper(const QString &fontFile, const QString &fontName, QObject *parent) : QObject(parent)
+{
+    //判断图形字体是否存在,不存在则加入
+    QFontDatabase fontDb;
+    if (!fontDb.families().contains(fontName) && QFile(fontFile).exists()) {
+        int fontId = fontDb.addApplicationFont(fontFile);
+        QStringList listName = fontDb.applicationFontFamilies(fontId);
+        if (listName.count() == 0) {
+            qDebug() << QString("load %1 error").arg(fontName);
+        }
+    }
+
+    //再次判断是否包含字体名称防止加载失败
+    if (fontDb.families().contains(fontName)) {
+        iconFont = QFont(fontName);
+#if (QT_VERSION >= QT_VERSION_CHECK(4,8,0))
+        iconFont.setHintingPreference(QFont::PreferNoHinting);
+#endif
+    }
+}
+
+bool IconHelper::eventFilter(QObject *watched, QEvent *event)
+{
+    //根据不同的
+    if (watched->inherits("QAbstractButton")) {
+        QAbstractButton *btn = (QAbstractButton *)watched;
+        int index = btns.indexOf(btn);
+        if (index >= 0) {
+            //不同的事件设置不同的图标,同时区分选中的和没有选中的
+            if (btn->isChecked()) {
+                if (event->type() == QEvent::MouseButtonPress) {
+                    QMouseEvent *mouseEvent = (QMouseEvent *)event;
+                    if (mouseEvent->button() == Qt::LeftButton) {
+                        btn->setIcon(QIcon(pixChecked.at(index)));
+                    }
+                } else if (event->type() == QEvent::Enter) {
+                    btn->setIcon(QIcon(pixChecked.at(index)));
+                } else if (event->type() == QEvent::Leave) {
+                    btn->setIcon(QIcon(pixChecked.at(index)));
+                }
+            } else {
+                if (event->type() == QEvent::MouseButtonPress) {
+                    QMouseEvent *mouseEvent = (QMouseEvent *)event;
+                    if (mouseEvent->button() == Qt::LeftButton) {
+                        btn->setIcon(QIcon(pixPressed.at(index)));
+                    }
+                } else if (event->type() == QEvent::Enter) {
+                    btn->setIcon(QIcon(pixHover.at(index)));
+                } else if (event->type() == QEvent::Leave) {
+                    btn->setIcon(QIcon(pixNormal.at(index)));
+                }
+            }
+        }
+    }
+
+    return QObject::eventFilter(watched, event);
+}
+
+void IconHelper::toggled(bool checked)
+{
+    //选中和不选中设置不同的图标
+    QAbstractButton *btn = (QAbstractButton *)sender();
+    int index = btns.indexOf(btn);
+    if (checked) {
+        btn->setIcon(QIcon(pixChecked.at(index)));
+    } else {
+        btn->setIcon(QIcon(pixNormal.at(index)));
+    }
+}
+
+QFont IconHelper::getIconFont()
+{
+    return this->iconFont;
+}
+
+void IconHelper::setIcon1(QLabel *lab, int icon, quint32 size)
+{
+    iconFont.setPixelSize(size);
+    lab->setFont(iconFont);
+    lab->setText((QChar)icon);
+}
+
+void IconHelper::setIcon1(QAbstractButton *btn, int icon, quint32 size)
+{
+    iconFont.setPixelSize(size);
+    btn->setFont(iconFont);
+    btn->setText((QChar)icon);
+}
+
+void IconHelper::setPixmap1(QAbstractButton *btn, const QColor &color, int icon, quint32 size,
+                            quint32 width, quint32 height, int flags)
+{
+    btn->setIcon(getPixmap1(color, icon, size, width, height, flags));
+}
+
+QPixmap IconHelper::getPixmap1(const QColor &color, int icon, quint32 size,
+                               quint32 width, quint32 height, int flags)
+{
+    //主动绘制图形字体到图片
+    QPixmap pix(width, height);
+    pix.fill(Qt::transparent);
+
+    QPainter painter;
+    painter.begin(&pix);
+    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+    painter.setPen(color);
+
+    iconFont.setPixelSize(size);
+    painter.setFont(iconFont);
+    painter.drawText(pix.rect(), flags, (QChar)icon);
+    painter.end();
+    return pix;
+}
+
+void IconHelper::setStyle1(QWidget *widget, QList<QPushButton *> btns, QList<int> icons, const IconHelper::StyleColor &styleColor)
+{
+    QList<QAbstractButton *> list;
+    foreach (QPushButton *btn, btns) {
+        list << btn;
+    }
+
+    setStyle(widget, list, icons, styleColor);
+}
+
+void IconHelper::setStyle1(QWidget *widget, QList<QToolButton *> btns, QList<int> icons, const IconHelper::StyleColor &styleColor)
+{
+    QList<QAbstractButton *> list;
+    foreach (QToolButton *btn, btns) {
+        list << btn;
+    }
+
+    setStyle(widget, list, icons, styleColor);
+}
+
+void IconHelper::setStyle1(QWidget *widget, QList<QAbstractButton *> btns, QList<int> icons, const IconHelper::StyleColor &styleColor)
+{
+    int btnCount = btns.count();
+    int iconCount = icons.count();
+    if (btnCount <= 0 || iconCount <= 0 || btnCount != iconCount) {
+        return;
+    }
+
+    QString position = styleColor.position;
+    quint32 iconSize = styleColor.iconSize;
+    quint32 iconWidth = styleColor.iconWidth;
+    quint32 iconHeight = styleColor.iconHeight;
+    quint32 borderWidth = styleColor.borderWidth;
+
+    //根据不同的位置计算边框
+    QString strBorder;
+    if (position == "top") {
+        strBorder = QString("border-width:%1px 0px 0px 0px;padding-top:%1px;padding-bottom:%2px;")
+                    .arg(borderWidth).arg(borderWidth * 2);
+    } else if (position == "right") {
+        strBorder = QString("border-width:0px %1px 0px 0px;padding-right:%1px;padding-left:%2px;")
+                    .arg(borderWidth).arg(borderWidth * 2);
+    } else if (position == "bottom") {
+        strBorder = QString("border-width:0px 0px %1px 0px;padding-bottom:%1px;padding-top:%2px;")
+                    .arg(borderWidth).arg(borderWidth * 2);
+    } else if (position == "left") {
+        strBorder = QString("border-width:0px 0px 0px %1px;padding-left:%1px;padding-right:%2px;")
+                    .arg(borderWidth).arg(borderWidth * 2);
+    }
+
+    //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色
+    //如果图标在文字上面而设置的边框是 top bottom 也需要启用加深边框
+    QStringList qss;
+    if (styleColor.defaultBorder) {
+        qss << QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}")
+            .arg(position).arg(strBorder).arg(styleColor.normalBgColor).arg(styleColor.normalTextColor).arg(styleColor.normalBgColor);
+    } else {
+        qss << QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}")
+            .arg(position).arg(styleColor.normalTextColor).arg(styleColor.normalBgColor);
+    }
+
+    //悬停+按下+选中
+    qss << QString("QWidget[flag=\"%1\"] QAbstractButton:hover{border-style:solid;%2border-color:%3;color:%4;background:%5;}")
+        .arg(position).arg(strBorder).arg(styleColor.borderColor).arg(styleColor.hoverTextColor).arg(styleColor.hoverBgColor);
+    qss << QString("QWidget[flag=\"%1\"] QAbstractButton:pressed{border-style:solid;%2border-color:%3;color:%4;background:%5;}")
+        .arg(position).arg(strBorder).arg(styleColor.borderColor).arg(styleColor.pressedTextColor).arg(styleColor.pressedBgColor);
+    qss << QString("QWidget[flag=\"%1\"] QAbstractButton:checked{border-style:solid;%2border-color:%3;color:%4;background:%5;}")
+        .arg(position).arg(strBorder).arg(styleColor.borderColor).arg(styleColor.checkedTextColor).arg(styleColor.checkedBgColor);
+
+    //窗体背景颜色+按钮背景颜色
+    qss << QString("QWidget#%1{background:%2;}")
+        .arg(widget->objectName()).arg(styleColor.normalBgColor);
+    qss << QString("QWidget>QAbstractButton{border-width:0px;background-color:%1;color:%2;}")
+        .arg(styleColor.normalBgColor).arg(styleColor.normalTextColor);
+    qss << QString("QWidget>QAbstractButton:hover{background-color:%1;color:%2;}")
+        .arg(styleColor.hoverBgColor).arg(styleColor.hoverTextColor);
+    qss << QString("QWidget>QAbstractButton:pressed{background-color:%1;color:%2;}")
+        .arg(styleColor.pressedBgColor).arg(styleColor.pressedTextColor);
+    qss << QString("QWidget>QAbstractButton:checked{background-color:%1;color:%2;}")
+        .arg(styleColor.checkedBgColor).arg(styleColor.checkedTextColor);
+
+    //设置样式表
+    widget->setStyleSheet(qss.join(""));
+
+    //可能会重复调用设置所以先要移除上一次的
+    for (int i = 0; i < btnCount; ++i) {
+        for (int j = 0; j < this->btns.count(); j++) {
+            if (this->btns.at(j) == btns.at(i)) {
+                disconnect(btns.at(i), SIGNAL(toggled(bool)), this, SLOT(toggled(bool)));
+                this->btns.at(j)->removeEventFilter(this);
+                this->btns.removeAt(j);
+                this->pixNormal.removeAt(j);
+                this->pixHover.removeAt(j);
+                this->pixPressed.removeAt(j);
+                this->pixChecked.removeAt(j);
+                break;
+            }
+        }
+    }
+
+    //存储对应按钮对象,方便鼠标移上去的时候切换图片
+    int checkedIndex = -1;
+    for (int i = 0; i < btnCount; ++i) {
+        int icon = icons.at(i);
+        QPixmap pixNormal = getPixmap1(styleColor.normalTextColor, icon, iconSize, iconWidth, iconHeight);
+        QPixmap pixHover = getPixmap1(styleColor.hoverTextColor, icon, iconSize, iconWidth, iconHeight);
+        QPixmap pixPressed = getPixmap1(styleColor.pressedTextColor, icon, iconSize, iconWidth, iconHeight);
+        QPixmap pixChecked = getPixmap1(styleColor.checkedTextColor, icon, iconSize, iconWidth, iconHeight);
+
+        //记住最后选中的按钮
+        QAbstractButton *btn = btns.at(i);
+        if (btn->isChecked()) {
+            checkedIndex = i;
+        }
+
+        btn->setIcon(QIcon(pixNormal));
+        btn->setIconSize(QSize(iconWidth, iconHeight));
+        btn->installEventFilter(this);
+        connect(btn, SIGNAL(toggled(bool)), this, SLOT(toggled(bool)));
+
+        this->btns << btn;
+        this->pixNormal << pixNormal;
+        this->pixHover << pixHover;
+        this->pixPressed << pixPressed;
+        this->pixChecked << pixChecked;
+    }
+
+    //主动触发一下选中的按钮
+    if (checkedIndex >= 0) {
+        QMetaObject::invokeMethod(btns.at(checkedIndex), "toggled", Q_ARG(bool, true));
+    }
+}

+ 184 - 0
core_ui/iconhelper.h

@@ -0,0 +1,184 @@
+#ifndef ICONHELPER_H
+#define ICONHELPER_H
+
+/**
+ * 超级图形字体类 作者:feiyangqingyun(QQ:517216493) 2016-11-23
+ * 1. 可传入多种图形字体文件,一个类通用所有图形字体。
+ * 2. 默认已经内置了阿里巴巴图形字体FontAliBaBa、国际知名图形字体FontAwesome、天气图形字体FontWeather。
+ * 3. 可设置 QLabel、QAbstractButton 文本为图形字体。
+ * 4. 可设置图形字体作为 QAbstractButton 按钮图标。
+ * 5. 内置万能的方法 getPixmap 将图形字体值转换为图片。
+ * 6. 无论是设置文本、图标、图片等都可以设置图标的大小、尺寸、颜色等参数。
+ * 7. 内置超级导航栏样式设置,将图形字体作为图标设置到按钮。
+ * 8. 支持各种颜色设置比如正常颜色、悬停颜色、按下颜色、选中颜色。
+ * 9. 可设置导航的位置为 left、right、top、bottom 四种。
+ * 10. 可设置导航加深边框颜色和粗细大小。
+ * 11. 导航面板的各种切换效果比如鼠标悬停、按下、选中等都自动处理掉样式设置。
+ * 12. 全局静态方法,接口丰富,使用极其简单方便。
+ */
+
+#include <QtGui>
+#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
+// #include <QtWidgets>
+#include <QtWidgets/QtWidgets>
+#endif
+
+#ifdef quc
+class Q_DECL_EXPORT IconHelper : public QObject
+#else
+class IconHelper : public QObject
+#endif
+
+{
+    Q_OBJECT
+
+private:
+    //阿里巴巴图形字体类
+    static IconHelper *iconFontAliBaBa;
+    //FontAwesome图形字体类
+    static IconHelper *iconFontAwesome;
+    //FontAwesome6图形字体类
+    static IconHelper *iconFontAwesome6;
+    //天气图形字体类
+    static IconHelper *iconFontWeather;
+    //图形字体索引
+    static int iconFontIndex;
+
+public:
+    //样式颜色结构体
+    struct StyleColor {
+        QString position;           //位置 left right top bottom
+        bool defaultBorder;         //默认有边框
+
+        quint32 iconSize;           //图标字体尺寸
+        quint32 iconWidth;          //图标图片宽度
+        quint32 iconHeight;         //图标图片高度
+
+        quint32 borderWidth;        //边框宽度
+        QString borderColor;        //边框颜色
+
+        QString normalBgColor;      //正常背景颜色
+        QString normalTextColor;    //正常文字颜色
+        QString hoverBgColor;       //悬停背景颜色
+        QString hoverTextColor;     //悬停文字颜色
+        QString pressedBgColor;     //按下背景颜色
+        QString pressedTextColor;   //按下文字颜色
+        QString checkedBgColor;     //选中背景颜色
+        QString checkedTextColor;   //选中文字颜色
+
+        StyleColor() {
+            position = "left";
+            defaultBorder = false;
+
+            iconSize = 12;
+            iconWidth = 15;
+            iconHeight = 15;
+
+            borderWidth = 3;
+            borderColor = "#029FEA";
+
+            normalBgColor = "#292F38";
+            normalTextColor = "#54626F";
+            hoverBgColor = "#40444D";
+            hoverTextColor = "#FDFDFD";
+            pressedBgColor = "#404244";
+            pressedTextColor = "#FDFDFD";
+            checkedBgColor = "#44494F";
+            checkedTextColor = "#FDFDFD";
+        }
+
+        //设置常规颜色 普通状态+加深状态
+        void setColor(const QString &normalBgColor,
+                      const QString &normalTextColor,
+                      const QString &darkBgColor,
+                      const QString &darkTextColor) {
+            this->normalBgColor = normalBgColor;
+            this->normalTextColor = normalTextColor;
+            this->hoverBgColor = darkBgColor;
+            this->hoverTextColor = darkTextColor;
+            this->pressedBgColor = darkBgColor;
+            this->pressedTextColor = darkTextColor;
+            this->checkedBgColor = darkBgColor;
+            this->checkedTextColor = darkTextColor;
+        }
+    };
+
+
+    //初始化图形字体
+    static void initFont();
+    //设置引用图形字体文件索引
+    static void setIconFontIndex(int index);
+
+    //获取图形字体
+    static QFont getIconFontAliBaBa();
+    static QFont getIconFontAwesome();
+    static QFont getIconFontAwesome6();
+    static QFont getIconFontWeather();
+
+    //根据值获取图形字体类
+    static IconHelper *getIconHelper(int icon);
+
+    //设置图形字体到标签
+    static void setIcon(QLabel *lab, int icon, quint32 size = 12);
+    //设置图形字体到按钮
+    static void setIcon(QAbstractButton *btn, int icon, quint32 size = 12);
+
+    //设置图形字体到图标
+    static void setPixmap(QAbstractButton *btn, const QColor &color,
+                          int icon, quint32 size = 12,
+                          quint32 width = 15, quint32 height = 15,
+                          int flags = Qt::AlignCenter);
+    //获取指定图形字体,可以指定文字大小,图片宽高,文字对齐
+    static QPixmap getPixmap(const QColor &color, int icon, quint32 size = 12,
+                             quint32 width = 15, quint32 height = 15,
+                             int flags = Qt::AlignCenter);
+
+    //指定导航面板样式,带图标和效果切换+悬停颜色+按下颜色+选中颜色
+    static void setStyle(QWidget *widget, QList<QPushButton *> btns, QList<int> icons, const StyleColor &styleColor);
+    static void setStyle(QWidget *widget, QList<QToolButton *> btns, QList<int> icons, const StyleColor &styleColor);
+    static void setStyle(QWidget *widget, QList<QAbstractButton *> btns, QList<int> icons, const StyleColor &styleColor);
+
+    //默认构造函数,传入字体文件+字体名称
+    explicit IconHelper(const QString &fontFile, const QString &fontName, QObject *parent = 0);
+
+protected:
+    bool eventFilter(QObject *watched, QEvent *event);
+
+private:
+    QFont iconFont;                 //图形字体
+    QList<QAbstractButton *> btns;  //按钮队列
+    QList<QPixmap> pixNormal;       //正常图片队列
+    QList<QPixmap> pixHover;        //悬停图片队列
+    QList<QPixmap> pixPressed;      //按下图片队列
+    QList<QPixmap> pixChecked;      //选中图片队列
+
+private slots:
+    //按钮选中状态切换处理
+    void toggled(bool checked);
+
+public:
+    //获取图形字体
+    QFont getIconFont();
+
+    //设置图形字体到标签
+    void setIcon1(QLabel *lab, int icon, quint32 size = 12);
+    //设置图形字体到按钮
+    void setIcon1(QAbstractButton *btn, int icon, quint32 size = 12);
+
+    //设置图形字体到图标
+    void setPixmap1(QAbstractButton *btn, const QColor &color,
+                    int icon, quint32 size = 12,
+                    quint32 width = 15, quint32 height = 15,
+                    int flags = Qt::AlignCenter);
+    //获取指定图形字体,可以指定文字大小,图片宽高,文字对齐
+    QPixmap getPixmap1(const QColor &color, int icon, quint32 size = 12,
+                       quint32 width = 15, quint32 height = 15,
+                       int flags = Qt::AlignCenter);
+
+    //指定导航面板样式,带图标和效果切换+悬停颜色+按下颜色+选中颜色
+    void setStyle1(QWidget *widget, QList<QPushButton *> btns, QList<int> icons, const StyleColor &styleColor);
+    void setStyle1(QWidget *widget, QList<QToolButton *> btns, QList<int> icons, const StyleColor &styleColor);
+    void setStyle1(QWidget *widget, QList<QAbstractButton *> btns, QList<int> icons, const StyleColor &styleColor);
+};
+
+#endif // ICONHELPER_H

+ 17 - 0
image.qrc

@@ -0,0 +1,17 @@
+<RCC>
+    <qresource prefix="/">
+        <file>qrc/image/album_blue.png</file>
+        <file>qrc/image/album_white.png</file>
+        <file>qrc/image/setting_blue.png</file>
+        <file>qrc/image/setting_white.png</file>
+        <file>qrc/image/upload_blue.png</file>
+        <file>qrc/image/upload_white.png</file>
+        <file>qrc/image/info_grey.png</file>
+        <file>qrc/image/copy_white.png</file>
+        <file>qrc/image/info_blue.png</file>
+        <file>qrc/image/icon.png</file>
+        <file>qrc/image/delete_red.png</file>
+        <file>qrc/image/delete_white.png</file>
+        <file>qrc/image/copy_blue.png</file>
+    </qresource>
+</RCC>

BIN
libcrypto.a


BIN
libcrypto.dll.a


BIN
libssl.a


BIN
libssl.dll.a


+ 23 - 0
main.cpp

@@ -0,0 +1,23 @@
+#include "widget.h"
+
+#include <QApplication>
+#include <QFile>
+
+int main(int argc, char *argv[])
+{
+    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+    QApplication a(argc, argv);
+    a.setFont(QFont("Microsoft YaHei UI"));
+    Widget w;
+    w.setWindowIcon(QIcon(QPixmap(":/qrc/image/icon.png")));
+    QFile qss(":/qrc/qss/blacksoft.qss");
+    if (qss.open(QFile::ReadOnly)) {
+        QString qss_str = QLatin1String(qss.readAll());
+//        w.setPalette(QPalette(QColor(63, 60, 55)));
+//        qApp->setPalette(QPalette(QColor(63, 60, 55)));
+        qApp->setStyleSheet(qss_str);
+        qss.close();
+    }
+    w.show();
+    return a.exec();
+}

+ 47 - 0
picpanel.pro

@@ -0,0 +1,47 @@
+QT       += core gui network
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+CONFIG += c++17 console
+
+# You can make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+    main.cpp \
+    widget.cpp
+
+HEADERS += \
+    widget.h
+
+FORMS += \
+    widget.ui
+
+INCLUDEPATH += $$PWD
+INCLUDEPATH += $$PWD/core_form
+INCLUDEPATH += $$PWD/core_ui
+INCLUDEPATH += $$PWD/core_support
+#include($$PWD/core_qui/core_qui.pri)
+include($$PWD/core_form/core_form.pri)
+include($$PWD/core_ui/core_ui.pri)
+include($$PWD/core_support/core_support.pri)
+
+CONFIG += QMAKE_CXXFLAGS_WARN_OFF
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+#OBJECTS_DIR = $$PWD/build/obj
+#MOC_DIR = $$PWD/build/moc
+#RCC_DIR = $$PWD/build/rcc
+#UI_DIR = $$PWD/build/ui
+
+#DESTDIR = $$PWD/build/bin
+
+RESOURCES += \
+    image.qrc \
+    qss.qrc \
+    ttf.qrc

+ 319 - 0
picpanel.pro.user

@@ -0,0 +1,319 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 4.11.1, 2025-03-24T00:02:57. -->
+<qtcreator>
+ <data>
+  <variable>EnvironmentId</variable>
+  <value type="QByteArray">{4f2ec396-c2e0-4f3d-a369-5968ecaf5cee}</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.ActiveTarget</variable>
+  <value type="int">0</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.EditorSettings</variable>
+  <valuemap type="QVariantMap">
+   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+    <value type="QString" key="language">Cpp</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+    </valuemap>
+   </valuemap>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+    <value type="QString" key="language">QmlJS</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+    </valuemap>
+   </valuemap>
+   <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
+   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+   <value type="int" key="EditorConfiguration.IndentSize">4</value>
+   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+   <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
+   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+   <value type="int" key="EditorConfiguration.TabSize">8</value>
+   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.PluginSettings</variable>
+  <valuemap type="QVariantMap">
+   <valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey">
+    <value type="QString">-fno-delayed-template-parsing</value>
+   </valuelist>
+   <value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Target.0</variable>
+  <valuemap type="QVariantMap">
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.14.2 MinGW 64-bit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.14.2 MinGW 64-bit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5142.win64_mingw73_kit</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:/Workspaces/build-picpanel-Desktop_Qt_5_14_2_MinGW_64_bit-Debug</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:/Workspaces/build-picpanel-Desktop_Qt_5_14_2_MinGW_64_bit-Release</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:/Workspaces/build-picpanel-Desktop_Qt_5_14_2_MinGW_64_bit-Profile</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+    <value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
+    <valuelist type="QVariantList" key="Analyzer.Perf.Events">
+     <value type="QString">cpu-cycles</value>
+    </valuelist>
+    <valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
+    <value type="int" key="Analyzer.Perf.Frequency">250</value>
+    <valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
+     <value type="QString">-e</value>
+     <value type="QString">cpu-cycles</value>
+     <value type="QString">--call-graph</value>
+     <value type="QString">dwarf,4096</value>
+     <value type="QString">-F</value>
+     <value type="QString">250</value>
+    </valuelist>
+    <value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
+    <value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
+    <value type="int" key="Analyzer.Perf.StackSize">4096</value>
+    <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:D:/Workspaces/picpanel/picpanel.pro</value>
+    <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">D:/Workspaces/picpanel/picpanel.pro</value>
+    <value type="QString" key="RunConfiguration.Arguments"></value>
+    <value type="bool" key="RunConfiguration.Arguments.multi">false</value>
+    <value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+    <value type="QString" key="RunConfiguration.WorkingDirectory"></value>
+    <value type="QString" key="RunConfiguration.WorkingDirectory.default">D:/Workspaces/build-picpanel-Desktop_Qt_5_14_2_MinGW_64_bit-Debug</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.TargetCount</variable>
+  <value type="int">1</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+  <value type="int">22</value>
+ </data>
+ <data>
+  <variable>Version</variable>
+  <value type="int">22</value>
+ </data>
+</qtcreator>

+ 270 - 0
picpanel/picpanel.pro.user

@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 14.0.2, 2024-10-15T14:29:17. -->
+<qtcreator>
+ <data>
+  <variable>EnvironmentId</variable>
+  <value type="QByteArray">{d9771540-486d-4f49-8184-6e87d1101478}</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.ActiveTarget</variable>
+  <value type="qlonglong">0</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.EditorSettings</variable>
+  <valuemap type="QVariantMap">
+   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+    <value type="QString" key="language">Cpp</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+    </valuemap>
+   </valuemap>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+    <value type="QString" key="language">QmlJS</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+    </valuemap>
+   </valuemap>
+   <value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
+   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+   <value type="int" key="EditorConfiguration.IndentSize">4</value>
+   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+   <value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
+   <value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
+   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
+   <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
+   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+   <value type="int" key="EditorConfiguration.TabSize">8</value>
+   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+   <value type="bool" key="EditorConfiguration.UseIndenter">false</value>
+   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+   <value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
+   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+   <value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
+   <value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.PluginSettings</variable>
+  <valuemap type="QVariantMap">
+   <valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
+    <value type="bool" key="AutoTest.Framework.Boost">true</value>
+    <value type="bool" key="AutoTest.Framework.CTest">false</value>
+    <value type="bool" key="AutoTest.Framework.Catch">true</value>
+    <value type="bool" key="AutoTest.Framework.GTest">true</value>
+    <value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
+    <value type="bool" key="AutoTest.Framework.QtTest">true</value>
+   </valuemap>
+   <value type="bool" key="AutoTest.ApplyFilter">false</value>
+   <valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
+   <valuelist type="QVariantList" key="AutoTest.PathFilters"/>
+   <value type="int" key="AutoTest.RunAfterBuild">0</value>
+   <value type="bool" key="AutoTest.UseGlobal">true</value>
+   <valuemap type="QVariantMap" key="ClangTools">
+    <value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
+    <value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
+    <value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
+    <value type="int" key="ClangTools.ParallelJobs">8</value>
+    <value type="bool" key="ClangTools.PreferConfigFile">true</value>
+    <valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
+    <valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
+    <valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
+    <value type="bool" key="ClangTools.UseGlobalSettings">true</value>
+   </valuemap>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Target.0</variable>
+  <valuemap type="QVariantMap">
+   <value type="QString" key="DeviceType">Desktop</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 6.7.3 for macOS</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Qt 6.7.3 for macOS</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.673.clang_64_kit</value>
+   <value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+   <value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+   <value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+    <value type="int" key="EnableQmlDebugging">0</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/lenn/Workspace/picpanel/picpanel/build/Qt_6_7_3_for_macOS-Debug</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/Users/lenn/Workspace/picpanel/picpanel/build/Qt_6_7_3_for_macOS-Debug</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+     </valuemap>
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+     </valuemap>
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/lenn/Workspace/picpanel/picpanel/build/Qt_6_7_3_for_macOS-Release</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/Users/lenn/Workspace/picpanel/picpanel/build/Qt_6_7_3_for_macOS-Release</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+     </valuemap>
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+     </valuemap>
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="int" key="QtQuickCompiler">0</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
+    <value type="int" key="EnableQmlDebugging">0</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/lenn/Workspace/picpanel/picpanel/build/Qt_6_7_3_for_macOS-Profile</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/Users/lenn/Workspace/picpanel/picpanel/build/Qt_6_7_3_for_macOS-Profile</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+     </valuemap>
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+     </valuemap>
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="int" key="QtQuickCompiler">0</value>
+    <value type="int" key="SeparateDebugInfo">0</value>
+   </valuemap>
+   <value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">部署</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
+    <value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+   </valuemap>
+   <value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+    <value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="CustomOutputParsers"/>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
+    <value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/Users/lenn/Workspace/picpanel/picpanel/picpanel.pro</value>
+    <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/Users/lenn/Workspace/picpanel/picpanel/picpanel.pro</value>
+    <value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+    <value type="QString" key="RunConfiguration.WorkingDirectory.default">/Users/lenn/Workspace/picpanel/picpanel/build/Qt_6_7_3_for_macOS-Debug/picpanel.app/Contents/MacOS</value>
+   </valuemap>
+   <value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.TargetCount</variable>
+  <value type="qlonglong">1</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+  <value type="int">22</value>
+ </data>
+ <data>
+  <variable>Version</variable>
+  <value type="int">22</value>
+ </data>
+</qtcreator>

BIN
qrc/image/album_blue.png


BIN
qrc/image/album_white.png


BIN
qrc/image/copy_blue.png


BIN
qrc/image/copy_white.png


BIN
qrc/image/delete_red.png


BIN
qrc/image/delete_white.png


BIN
qrc/image/icon.png


BIN
qrc/image/info_blue.png


BIN
qrc/image/info_grey.png


BIN
qrc/image/setting_blue.png


BIN
qrc/image/setting_white.png


BIN
qrc/image/upload_blue.png


BIN
qrc/image/upload_white.png


+ 192 - 0
qrc/qss/blacksoft.qss

@@ -0,0 +1,192 @@
+/* QPalette{background-color: rgb(63, 60, 55);} */
+
+QWidget#Widget{
+    background-color: rgb(63, 60, 55);
+    border: none;
+    border: 1px solid rgb(63, 60, 55);
+    border-radius: 15px;
+}
+
+QFrame#frmTop > QLabel{
+    font-family: 'Microsoft YaHei UI';
+    color: white;
+}
+
+QFrame#frmTop > QPushButton {
+    color: white;
+}
+
+QPushButton#btnClose:hover {
+    color:#F15140;
+}
+
+QPushButton#btnClose:pressed {
+    background-color: rgb(63, 60, 55);
+    border: none;
+}
+
+QPushButton#btnMin:hover {
+    color: #407AB4;
+}
+
+QPushButton#btnMin:pressed {
+    background-color: rgb(63, 60, 55);
+    border: none;
+}
+
+QFrame#frame > QPushButton {
+    font-family: 'Microsoft YaHei UI';
+    font-size: 20px;
+    color: white;
+}
+
+QPushButton#btnPageUpload {
+    text-align: left;
+}
+
+QPushButton#btnPageUpload:hover {
+    color: #409EFF;
+    /* border: none; */
+    /* border-left: 2px solid #407AB4; */
+}
+
+QPushButton#btnPageUpload:checked {
+    border: none;
+    border-right: 4px solid #409EFF;
+    color: #409EFF;
+}
+
+QPushButton#btnPageUpload:pressed {
+    background-color: rgb(63, 60, 55);
+    border: none;
+}
+
+QPushButton#btnPageAlbum {
+    text-align: left;
+}
+
+QPushButton#btnPageAlbum:hover {
+    color: #409EFF;
+}
+
+QPushButton#btnPageAlbum:checked {
+    border: none;
+    border-right: 4px solid #409EFF;
+    color: #409EFF;
+}
+
+QPushButton#btnPageAlbum:pressed {
+    background-color: rgb(63, 60, 55);
+    border: none;
+}
+
+QPushButton#btnPageSetting {
+    text-align: left;
+}
+
+QPushButton#btnPageSetting:hover {
+    color: #409EFF;
+}
+
+QPushButton#btnPageSetting:checked {
+    border: none;
+    border-right: 4px solid #409EFF;
+    color: #409EFF;
+}
+
+QPushButton#btnPageSetting:pressed {
+    background-color: rgb(63, 60, 55);
+    border: none;
+}
+
+
+/* 上传区 */
+QFrame#frmUpload {
+    border-radius: 15px;
+    border: 2px dashed white;
+}
+
+QFrame#frmUpload:hover {
+    border-radius: 15px;
+    border: 2px dashed #A4D8FA;
+    background-color: #5E6B71;
+}
+
+/* 右键菜单 */
+QMenu {
+    border: none;
+}
+
+QAction {
+    border: none;
+}
+
+QMessageBox > QLabel {
+    color: black;
+}
+
+QMessageBox > QToolButton {
+    color: black;
+}
+
+QMessageBox > QAbstractButton {
+    color: black;
+}
+
+/* 设置界面 */
+QWidget#FrmSetting > QLabel {
+    font-family: 'Microsoft YaHei UI';
+    color: white;
+}
+
+QWidget#FrmSetting > QPushButton {
+    border-radius: 15px;
+    border: none;
+    background-color: #409EFF;
+    font-family: 'Microsoft YaHei UI';
+    font-size: 15px;
+    color: white;
+}
+
+QPushButton#btnServer:hover {
+    background-color: #79BBFF;
+}
+
+/* server设置 */
+QWidget#ServerSetting {
+    border: none;
+    border: 1px solid white;
+    border-radius: 15px;
+}
+
+QWidget#ServerSetting > QPushButton#btnOk {
+    font-family: 'Microsoft YaHei UI';
+    background-color: #66B1FF;
+    border: 2px solid #66B1FF;
+    border-radius: 10px;;
+    color: white;
+    padding-left: 20px;
+    padding-right: 20px;
+    padding-top: 8px;
+    padding-bottom: 8px;
+}
+
+QWidget#ServerSetting > QPushButton#btnCencel {
+    font-family: 'Microsoft YaHei UI';
+    background-color: white;
+    border: 2px solid #DCDFE6;
+    border-radius: 10px;
+    color: black;
+}
+
+QWidget#ServerSetting > QLabel {
+    font-family: 'Microsoft YaHei UI';
+    color: black;
+}
+
+QWidget#ServerSetting > QLineEdit {
+    font-family: 'Microsoft YaHei UI';
+    border: 2px solid #DCDFE6;
+    background-color: white;
+    color: black;
+}

BIN
qrc/ttf/fa-regular-400.ttf


BIN
qrc/ttf/fontawesome-webfont.ttf


BIN
qrc/ttf/iconfont.ttf


BIN
qrc/ttf/pe-icon-set-weather.ttf


+ 5 - 0
qss.qrc

@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/">
+        <file>qrc/qss/blacksoft.qss</file>
+    </qresource>
+</RCC>

+ 8 - 0
ttf.qrc

@@ -0,0 +1,8 @@
+<RCC>
+    <qresource prefix="/">
+        <file>qrc/ttf/fa-regular-400.ttf</file>
+        <file>qrc/ttf/fontawesome-webfont.ttf</file>
+        <file>qrc/ttf/iconfont.ttf</file>
+        <file>qrc/ttf/pe-icon-set-weather.ttf</file>
+    </qresource>
+</RCC>

+ 353 - 0
widget.cpp

@@ -0,0 +1,353 @@
+#include "widget.h"
+#include "ui_widget.h"
+#include "tchttpservice.h"
+
+Widget::Widget(QWidget *parent)
+    : QWidget(parent)
+    , ui(new Ui::Widget)
+{
+    ui->setupUi(this);
+    initWidgetForm();
+    initWidget();
+    initSignalSlot();
+
+}
+
+Widget::~Widget()
+{
+    delete fileConfig;
+    delete ui;
+}
+
+bool Widget::eventFilter(QObject *watched, QEvent *event)
+{
+    static QPoint mousePoint;
+    static bool mousePressed = false;
+
+
+    if (watched == btnPageUpload) {
+        if (event->type() == QEvent::Enter) {
+            QIcon icon(":/qrc/image/upload_blue.png");
+            btnPageUpload->setIcon(icon);
+            return true;
+        }
+        else if (event->type() == QEvent::Leave && !btnPageUpload->isChecked()) {
+            QIcon icon(":/qrc/image/upload_white.png");
+            btnPageUpload->setIcon(icon);
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    if (watched == btnPageAlbum) {
+        if (event->type() == QEvent::Enter) {
+            QIcon icon(":/qrc/image/album_blue.png");
+            btnPageAlbum->setIcon(icon);
+            return true;
+        }
+        else if (event->type() == QEvent::Leave && !btnPageAlbum->isChecked()) {
+            QIcon icon(":/qrc/image/album_white.png");
+            btnPageAlbum->setIcon(icon);
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    if (watched == btnPageSetting) {
+        if (event->type() == QEvent::Enter) {
+            QIcon icon(":/qrc/image/setting_blue.png");
+            btnPageSetting->setIcon(icon);
+            return true;
+        }
+        else if (event->type() == QEvent::Leave && !btnPageSetting->isChecked()) {
+            QIcon icon(":/qrc/image/setting_white.png");
+            btnPageSetting->setIcon(icon);
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    if (watched == labAbout) {
+        if (event->type() == QEvent::Enter) {
+            labAbout->setPixmap(QPixmap(":/qrc/image/info_blue.png"));
+            return true;
+        }
+        else if (event->type() == QEvent::Leave) {
+            labAbout->setPixmap(QPixmap(":/qrc/image/info_grey.png"));
+            return true;
+        }
+
+        static bool labAboutPress = false;
+        QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
+        if (mouseEvent->type() == QMouseEvent::MouseButtonPress && mouseEvent->button() == Qt::LeftButton) {
+            labAboutPress = true;
+            return true;
+        }
+        else if (mouseEvent->type() == QMouseEvent::MouseButtonRelease && labAboutPress && mouseEvent->button() == Qt::LeftButton) {
+            QPoint pos = QCursor::pos();
+            menuPop->popup(pos);
+            return true;
+        }
+        else {
+            return false;
+        }
+
+    }
+
+    if (watched->objectName() == "frmTop") {
+        QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
+        if (mouseEvent->type() == QEvent::MouseButtonPress) {
+            if (mouseEvent->button() == Qt::LeftButton) {
+                mousePressed = true;
+                mousePoint = mouseEvent->globalPos() - this->pos();
+            }
+        }
+        else if (mouseEvent->type() == QEvent::MouseButtonRelease){
+            mousePressed = false;
+        }
+        else if (mouseEvent->type() == QEvent::MouseMove) {
+            if (mousePressed) {
+                this->move(mouseEvent->globalPos() - mousePoint);
+                return true;
+            }
+        }
+    }
+
+    return QWidget::eventFilter(watched, event);
+}
+
+void Widget::paintEvent(QPaintEvent *event)
+{
+//    QPainter painter(this);
+//    painter.setRenderHint(QPainter::Antialiasing);
+//    painter.setPen(Qt::NoPen);
+//    painter.setBrush(QColor("#3F3C37"));
+
+//    painter.drawRoundedRect(rect(), 15, 15);
+
+//    QWidget::paintEvent(event);
+    QStyleOption opt;
+    opt.init(this);
+    QPainter painter(this);
+    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
+}
+
+void Widget::initWidgetForm()
+{
+    this->setFixedSize(QSize(1000, 550));
+    this->setWindowFlag(Qt::FramelessWindowHint);
+    this->setWindowFlags(this->windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
+    this->setWindowIcon(QIcon(QPixmap(":/qrc/image/icon.png")));
+
+    this->setAttribute(Qt::WA_TranslucentBackground);
+
+    initLeftMenu();
+
+    ui->btnMin->setFlat(true);
+    ui->btnClose->setFlat(true);
+
+    IconHelper::setIconFontIndex(2);
+
+    IconHelper::setIcon(ui->btnMin, QString("F068").toInt(nullptr, 16), 16);
+    IconHelper::setIcon(ui->btnClose, QString("F00D").toInt(nullptr, 16), 16);
+
+    ui->labTitle->setText("PicPanel");
+}
+
+void Widget::initWidget()
+{
+    menuPop = new QMenu;
+    actAbout = new QAction;
+    actRcode = new QAction;
+    actPrivateLic = new QAction;
+
+    actAbout->setText("关于");
+    actRcode->setText("生成配置二维码");
+    actPrivateLic->setText("隐私协议");
+
+    menuPop->addAction(actAbout);
+    menuPop->addAction(actRcode);
+    menuPop->addAction(actPrivateLic);
+
+    connect(actAbout, &QAction::triggered, this, &Widget::actAboutSlot);
+    connect(actRcode, &QAction::triggered, this, &Widget::actRcodeSlot);
+    connect(actPrivateLic, &QAction::triggered, this, &Widget::actPrivateLicSlot);
+
+    ui->frmTop->installEventFilter(this);
+
+    btnPageUpload->setChecked(true);
+    ui->stackedWidget->setCurrentIndex(0);
+}
+
+void Widget::initSignalSlot()
+{
+    QList<QPushButton*> btns = ui->frame->findChildren<QPushButton*>();
+    foreach (QPushButton* b, btns) {
+        b->setFlat(true);
+        connect(b, &QPushButton::clicked, this, &Widget::pageChangeSlot);
+        b->installEventFilter(this);
+    }
+
+}
+
+void Widget::initLeftMenu()
+{
+    frmupload = new FrmUpload;
+    frmalbum = new FrmAlbum;
+    fileConfig = new FileConfigDecode();
+    frmsetting = new FrmSetting(fileConfig);
+
+    ui->frmTop->setPalette(QPalette(QColor(63, 60, 55)));
+
+    btnPageUpload = new QPushButton(ui->frame);
+    btnPageUpload->setObjectName("btnPageUpload");
+    btnPageUpload->setFlat(true);
+    btnPageUpload->setCursor(Qt::PointingHandCursor);
+    btnPageUpload->setText("上传区");
+    btnPageUpload->setMinimumWidth(160);
+    btnPageUpload->setMinimumHeight(30);
+    btnPageUpload->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
+    QIcon iconUpload(QPixmap(":/qrc/image/upload_white.png"));
+    btnPageUpload->setIconSize(QSize(24, 24));
+    btnPageUpload->setIcon(iconUpload);
+
+    btnPageAlbum = new QPushButton(ui->frame);
+    btnPageAlbum->setObjectName("btnPageAlbum");
+    btnPageAlbum->setFlat(true);
+    btnPageAlbum->setCursor(Qt::PointingHandCursor);
+    btnPageAlbum->setText("相册");
+    btnPageAlbum->setMinimumWidth(160);
+    btnPageAlbum->setMinimumHeight(30);
+    btnPageAlbum->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
+    QIcon iconAlbum(QPixmap(":/qrc/image/album_white.png"));
+    btnPageAlbum->setIconSize(QSize(24, 24));
+    btnPageAlbum->setIcon(iconAlbum);
+
+    btnPageSetting = new QPushButton(ui->frame);
+    btnPageSetting->setObjectName("btnPageSetting");
+    btnPageSetting->setFlat(true);
+    btnPageSetting->setCursor(Qt::PointingHandCursor);
+    btnPageSetting->setText("PicPanel设置");
+    btnPageSetting->setMinimumWidth(160);
+    btnPageSetting->setMinimumHeight(30);
+    btnPageSetting->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
+    QIcon iconSetting(QPixmap(":/qrc/image/setting_white.png"));
+    btnPageSetting->setIconSize(QSize(24, 24));
+    btnPageSetting->setIcon(iconSetting);
+
+    ui->stackedWidget->addWidget(frmupload);
+    ui->stackedWidget->addWidget(frmalbum);
+    ui->stackedWidget->addWidget(frmsetting);
+
+    QVBoxLayout* frameLayout = new QVBoxLayout;
+    frameLayout->setContentsMargins(0, 0, 0, 0);
+    frameLayout->setSpacing(0);
+    QSpacerItem* verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
+    frameLayout->addWidget(btnPageUpload);
+    frameLayout->addWidget(btnPageAlbum);
+    frameLayout->addWidget(btnPageSetting);
+    frameLayout->addSpacerItem(verticalSpacer);
+
+    QHBoxLayout* buttomLayout = new QHBoxLayout;
+    labAbout = new QLabel;
+    QSpacerItem* horizenSpacer = new QSpacerItem(250, 20, QSizePolicy::Minimum, QSizePolicy::Minimum);
+    labAbout->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+    labAbout->setMaximumSize(32, 32);
+    QPixmap pixInfo(":/qrc/image/info_grey.png");
+    labAbout->setPixmap(pixInfo);
+    labAbout->installEventFilter(this);
+    buttomLayout->addWidget(labAbout);
+    buttomLayout->addSpacerItem(horizenSpacer);
+    buttomLayout->setMargin(0);
+
+    frameLayout->addItem(buttomLayout);
+    frameLayout->setSpacing(40);
+    ui->frame->setLayout(frameLayout);
+}
+
+
+
+void Widget::on_btnClose_clicked()
+{
+    close();
+}
+
+void Widget::on_btnMin_clicked()
+{
+    showMinimized();
+}
+
+void Widget::pageChangeSlot()
+{
+    QPushButton* btn = (QPushButton*)sender();
+
+    QList<QPushButton*> btns = ui->frame->findChildren<QPushButton*>();
+    foreach (QPushButton* b, btns) {
+        b->setCheckable(true);
+        if (b == btn) {
+            b->setChecked(true);
+        }
+        else {
+            b->setChecked(false);
+        }
+    }
+    QIcon iconUploadWhite(":/qrc/image/upload_white.png");
+    QIcon iconAlbumWhite(":/qrc/image/album_white.png");
+    QIcon iconSettingWhite(":/qrc/image/setting_white.png");
+    QIcon iconUploadBule(":/qrc/image/upload_blue.png");
+    QIcon iconAlbumBlue(":/qrc/image/album_blue.png");
+    QIcon iconSettingBlue(":/qrc/image/setting_blue.png");
+
+    if (btn->objectName() == "btnPageUpload") {
+        btn->setIcon(iconUploadBule);
+        btnPageAlbum->setIcon(iconAlbumWhite);
+        btnPageSetting->setIcon(iconSettingWhite);
+        ui->stackedWidget->setCurrentWidget(frmupload);
+    }
+    else if (btn->text() == "相册") {
+        btn->setIcon(iconAlbumBlue);
+        btnPageUpload->setIcon(iconUploadWhite);
+        btnPageSetting->setIcon(iconSettingWhite);
+        ui->stackedWidget->setCurrentWidget(frmalbum);
+    }
+    else {
+        btn->setIcon(iconSettingBlue);
+        btnPageAlbum->setIcon(iconAlbumWhite);
+        btnPageUpload->setIcon(iconUploadWhite);
+        ui->stackedWidget->setCurrentWidget(frmsetting);
+    }
+}
+
+void Widget::actAboutSlot()
+{
+
+}
+
+void Widget::actRcodeSlot()
+{
+
+}
+
+void Widget::actPrivateLicSlot()
+{
+    qDebug() << "prv";
+    QMessageBox::information(this, "隐私协议", "本软件尊重并保护所有使用服务用户的个人隐私权,为了给您提供更准确、"
+                                           "更优质的服务,本软件会按照本隐私权政策的规定使用和收集您的一些行为信息。您在同意本软件服务使用协议之时,即视"
+                                           "为您已经同意本隐私权政策全部内容。本隐私权政策属于本软件服务使用协议不可分割的一部分,如果不同意将无法使用。本协议会定期更新。<br><br>"
+                             "1.适用范围<br><br>"
+                             "a)在您使用本软件时,本软件会记录的您对本软件的一些操作行为信息,包括但不限于您使用本软件进行文件上传的耗时、类型、数量等信息。<br><br>"
+                             "2.信息的使用<br><br>"
+                             "a)在获得悠的使用数据之后,本软件会将其上传至数据分析服务器,以便分析数据后,提供给您更好的服务<br><br>"
+                             "3.信息披露<br><br>"
+                             "a)本软件不会将您的信息披露给不受信任的第三方。<br><br>"
+                             "b)根据法律的有关规定,或者行政或司法机构的要求,向第三方或者行政、司法机构披露<br><br>"
+                             "c)如您出现违反中国有关法律、法规或者相关规则的情况,需要向第三方披露<br><br>"
+                             "4.信息安全<br><br>"
+                             "a)本软件不会收集您的个人信息、密钥信息等隐私信息,所收集的信息仅仅作为改善软件、优化体验、了解软件日活等用途。");
+}

+ 77 - 0
widget.h

@@ -0,0 +1,77 @@
+#ifndef WIDGET_H
+#define WIDGET_H
+
+#include <QWidget>
+#include <QLayout>
+#include <QSpacerItem>
+#include <QDebug>
+#include <QButtonGroup>
+#include <QEvent>
+#include <QDragMoveEvent>
+#include <QDragEnterEvent>
+#include <QEvent>
+#include <QPaintEvent>
+#include <QMessageBox>
+#include "fileconfigdecode.h"
+#include "frmalbum.h"
+#include "frmsetting.h"
+#include "frmupload.h"
+#include "iconhelper.h"
+
+class QPushButton;
+
+QT_BEGIN_NAMESPACE
+namespace Ui {
+class Widget;
+}
+QT_END_NAMESPACE
+
+class Widget : public QWidget
+{
+    Q_OBJECT
+
+public:
+    Widget(QWidget *parent = nullptr);
+    ~Widget();
+
+protected:
+    virtual bool eventFilter(QObject* watched, QEvent* event);
+
+    virtual void paintEvent(QPaintEvent* event);
+
+private slots:
+    void on_btnClose_clicked();
+
+    void on_btnMin_clicked();
+
+private slots:
+    void pageChangeSlot();
+    void actAboutSlot();
+    void actRcodeSlot();
+    void actPrivateLicSlot();
+private:
+    void initWidgetForm();
+    void initWidget();
+    void initSignalSlot();
+    void initLeftMenu();
+
+private:
+    Ui::Widget *ui;
+    FrmUpload* frmupload;
+    FrmAlbum* frmalbum;
+    FrmSetting* frmsetting;
+
+    QPushButton* btnPageUpload;
+    QPushButton* btnPageAlbum;
+    QPushButton* btnPageSetting;
+    QLabel* labAbout;
+
+    QMenu* menuPop;
+    QAction* actAbout;
+    QAction* actRcode;
+    QAction* actPrivateLic;
+
+    FileConfigDecode* fileConfig;
+
+};
+#endif // WIDGET_H

+ 176 - 0
widget.ui

@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Widget</class>
+ <widget class="QWidget" name="Widget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Widget</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="spacing">
+    <number>6</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="QFrame" name="frmTop">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::NoFrame</enum>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <property name="spacing">
+       <number>0</number>
+      </property>
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QLabel" name="labTitle">
+        <property name="text">
+         <string>TextLabel</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer_2">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="btnMin">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>40</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="btnClose">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>40</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QFrame" name="frame">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>200</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="frameShape">
+        <enum>QFrame::NoFrame</enum>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QStackedWidget" name="stackedWidget">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>