Преглед изворни кода

有个不必现错误,预览初步完成

lennlouis пре 4 недеља
родитељ
комит
d86f80982d

+ 2 - 0
core_form/core_form.pri

@@ -7,6 +7,7 @@ INCLUDEPATH += $$PWD/frmalbum
 INCLUDEPATH += $$PWD/frmimgshow
 INCLUDEPATH += $$PWD/frmimgshow
 INCLUDEPATH += $$PWD/switchbutton
 INCLUDEPATH += $$PWD/switchbutton
 INCLUDEPATH += $$PWD/serversetting
 INCLUDEPATH += $$PWD/serversetting
+INCLUDEPATH += $$PWD/panelwidget
 
 
 include($$PWD/frmupload/frmupload.pri)
 include($$PWD/frmupload/frmupload.pri)
 include($$PWD/frmsetting/frmsetting.pri)
 include($$PWD/frmsetting/frmsetting.pri)
@@ -14,3 +15,4 @@ include($$PWD/frmalbum/frmalbum.pri)
 include($$PWD/frmimgshow/frmimgshow.pri)
 include($$PWD/frmimgshow/frmimgshow.pri)
 include($$PWD/switchbutton/switchbutton.pri)
 include($$PWD/switchbutton/switchbutton.pri)
 include($$PWD/serversetting/serversetting.pri)
 include($$PWD/serversetting/serversetting.pri)
+include($$PWD/panelwidget/panelwidget.pri)

+ 36 - 4
core_form/frmalbum/frmalbum.cpp

@@ -1,14 +1,46 @@
 #include "frmalbum.h"
 #include "frmalbum.h"
 #include "ui_frmalbum.h"
 #include "ui_frmalbum.h"
+#include <QUrl>
 
 
-FrmAlbum::FrmAlbum(QWidget *parent)
-    : QWidget(parent)
-    , ui(new Ui::FrmAlbum)
+
+FrmAlbum::FrmAlbum(QWidget *parent) : QWidget(parent)
 {
 {
-    ui->setupUi(this);
+    initForm();
 }
 }
 
 
 FrmAlbum::~FrmAlbum()
 FrmAlbum::~FrmAlbum()
 {
 {
     delete ui;
     delete ui;
 }
 }
+
+void FrmAlbum::initForm()
+{
+    layout = new QHBoxLayout(this);
+    panelWidget = new PanelWidget(this);
+    layout->addWidget(panelWidget);
+    layout->setContentsMargins(0, 0, 0, 0);
+    layout->setSpacing(0);
+    this->setLayout(layout);
+    panelWidget->setObjectName("widget");
+    panelWidget->setStyleSheet("background-color: rgb(63, 60, 55)");
+    panelWidget->setAutoHeight(false);
+    panelWidget->setAutoWidth(false);
+    panelWidget->setAutoHeight(false);
+    panelWidget->setAutoWidth(false);
+
+    // qDebug() << ui->widget;
+
+    QList<QUrl> urls = {
+        QUrl("https://imagehyj.oss-cn-hangzhou.aliyuncs.com/blog/20250320201317.png"),
+        QUrl("https://imagehyj.oss-cn-hangzhou.aliyuncs.com/blog/EDH386.jpeg"),
+        QUrl("https://imagehyj.oss-cn-hangzhou.aliyuncs.com/blog/20250321103557.png"),
+    };
+
+    foreach (const QUrl& u, urls) {
+        FrmImgShow* widget  = new FrmImgShow(this);
+        widget->loadImage(u);
+        picWidgetList.push_front(widget);
+    }
+
+    panelWidget->setWidget(picWidgetList, 3);
+}

+ 7 - 0
core_form/frmalbum/frmalbum.h

@@ -2,6 +2,9 @@
 #define FRMALBUM_H
 #define FRMALBUM_H
 
 
 #include <QWidget>
 #include <QWidget>
+#include "panelwidget.h"
+#include "frmimgshow.h"
+#include <QHBoxLayout>
 
 
 namespace Ui {
 namespace Ui {
 class FrmAlbum;
 class FrmAlbum;
@@ -17,6 +20,10 @@ public:
 
 
 private:
 private:
     Ui::FrmAlbum *ui;
     Ui::FrmAlbum *ui;
+    QList<QWidget*> picWidgetList;
+    PanelWidget* panelWidget;
+    QHBoxLayout* layout;
+    void initForm();
 };
 };
 
 
 #endif // FRMALBUM_H
 #endif // FRMALBUM_H

+ 19 - 2
core_form/frmalbum/frmalbum.ui

@@ -6,13 +6,30 @@
    <rect>
    <rect>
     <x>0</x>
     <x>0</x>
     <y>0</y>
     <y>0</y>
-    <width>400</width>
-    <height>300</height>
+    <width>632</width>
+    <height>414</height>
    </rect>
    </rect>
   </property>
   </property>
   <property name="windowTitle">
   <property name="windowTitle">
    <string>Form</string>
    <string>Form</string>
   </property>
   </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>
+  </layout>
  </widget>
  </widget>
  <resources/>
  <resources/>
  <connections/>
  <connections/>

+ 101 - 60
core_form/frmimgshow/frmimgshow.cpp

@@ -1,47 +1,84 @@
 #include "frmimgshow.h"
 #include "frmimgshow.h"
 
 
-FrmImgShow::FrmImgShow(QString& url, QWidget *parent) : QWidget(parent)
+FrmImgShow::FrmImgShow(QWidget *parent) : QWidget(parent)
 {
 {
     initForm();
     initForm();
-    initForm();
-    initManager();
-    this->url = url;
-    manager->get(QNetworkRequest(QUrl(url)));
+    connect(TCHttpService::getInstance(), &TCHttpService::signal_imageDownloaded,
+            this, [this](const QString& requestId, const QPixmap& pixmap){
+        if (requestId == m_requestId) {
+            setLoadingState(false);
+            setImage(pixmap);
+        }
+    });
+
+    connect(TCHttpService::getInstance(), &TCHttpService::signal_downloadFailed,
+            this, [this](const QString& requestId, const QString& error){
+        if (requestId == m_requestId) {
+            setLoadingState(true);
+        }
+    });
 }
 }
 
 
-bool FrmImgShow::eventFilter(QObject *watched, QEvent *event)
+void FrmImgShow::loadImage(const QUrl &imageUrl)
 {
 {
-    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;
-        }
-    }
+    qDebug() << "loadImage";
+    m_currentUrl = imageUrl;
+    m_requestId = QUuid::createUuid().toString();
+    setLoadingState(true);
+    qDebug() << "downlaodImage";
+    TCHttpService::getInstance()->downloadImage(m_requestId, imageUrl);
+}
 
 
-    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;
-        }
-    }
+void FrmImgShow::setImage(const QPixmap &pixmap)
+{
+    qDebug() << "setImage";
+    labImg->setPixmap(pixmap.scaled(200, 200, Qt::KeepAspectRatio, Qt::SmoothTransformation));
+}
+
+void FrmImgShow::setLoadingState(bool loading)
+{
 
 
-    return QWidget::eventFilter(watched, event);
 }
 }
 
 
+
+QSize FrmImgShow::sizeHint()
+{
+    return QSize(300, 300);
+}
+
+// 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)
 void FrmImgShow::onFinished(QNetworkReply *reply)
 {
 {
     if (reply->error() == QNetworkReply::NoError) {
     if (reply->error() == QNetworkReply::NoError) {
@@ -54,39 +91,43 @@ void FrmImgShow::onFinished(QNetworkReply *reply)
 
 
 void FrmImgShow::initForm()
 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();
+    labImg = new QLabel(this);
+    // btnCopy = new QPushButton(this);
+    // btnCopy->setMaximumHeight(18);
+    // btnDelete = new QPushButton(this);
+    // btnDelete->setMaximumHeight(18);
+    // horizenSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+    // hLayout = new QHBoxLayout();
 
 
-    hLayout->addWidget(btnCopy);
-    hLayout->addSpacerItem(horizenSpacer);
+    // ckbSelect = new QCheckBox(this);
+    // ckbSelect->setMaximumHeight(18);
+    // hLayout->addWidget(btnCopy);
+    // hLayout->addWidget(btnDelete);
+    // hLayout->setContentsMargins(0, 0, 0, 0);
+    // hLayout->addSpacerItem(horizenSpacer);
+    // hLayout->addWidget(ckbSelect);
+    vLayout = new QVBoxLayout();
     vLayout->addWidget(labImg);
     vLayout->addWidget(labImg);
-    vLayout->addLayout(hLayout);
+    // vLayout->addLayout(hLayout);
+    vLayout->setContentsMargins(0, 0, 0, 0);
+    // vLayout->addLayout(vLayout);
+
     this->setLayout(vLayout);
     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);
-}
+    // 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);
+    setStyleSheet("background-color: #FF0000;border: 1px solid white");
+
+    setFixedSize(140, 160);
+
+    this->labImg->setFixedSize(140, 140);
 }
 }
 
 
-void FrmImgShow::initManager()
+void FrmImgShow::initWidget()
 {
 {
-    manager = new QNetworkAccessManager();
-    QClipboard* clipboard = QGuiApplication::clipboard();
-    connect(manager, &QNetworkAccessManager::finished,
-            this, &FrmImgShow::onFinished);
-
-    connect(btnCopy, &QToolButton::clicked, [&](){
-        clipboard->setText(this->url);
-    });
+    // btnCopy->installEventFilter(this);
+    // btnDelete->installEventFilter(this);
 }
 }

+ 17 - 14
core_form/frmimgshow/frmimgshow.h

@@ -8,32 +8,36 @@
 #include <QVBoxLayout>
 #include <QVBoxLayout>
 #include <QToolButton>
 #include <QToolButton>
 #include <QSpacerItem>
 #include <QSpacerItem>
-#include <QNetworkAccessManager>
-#include <QNetworkRequest>
 #include <QUrl>
 #include <QUrl>
-#include <QNetworkReply>
-#include <QClipboard>
+#include <QCheckBox>
 #include <QGuiApplication>
 #include <QGuiApplication>
+#include "tchttpservice.h"
 
 
 class FrmImgShow : public QWidget
 class FrmImgShow : public QWidget
 {
 {
     Q_OBJECT
     Q_OBJECT
 public:
 public:
-    explicit FrmImgShow(QString& url, QWidget *parent = nullptr);
+    explicit FrmImgShow(QWidget *parent = nullptr);
 
 
+    void loadImage(const QUrl& imageUrl);
+    void setImage(const QPixmap& pixmap);
+    void setLoadingState(bool loading);
+
+    QSize sizeHint();
 private:
 private:
     QLabel* labImg;
     QLabel* labImg;
-    QToolButton* btnCopy;
-    QToolButton* btnDelete;
+    // QLabel* labLoading;
+    // QMovie* movieLoading;
+
+    QPushButton* btnCopy;
+    QPushButton* btnDelete;
     QSpacerItem* horizenSpacer;
     QSpacerItem* horizenSpacer;
     QHBoxLayout* hLayout;
     QHBoxLayout* hLayout;
+    QCheckBox* ckbSelect;
     QVBoxLayout* vLayout;
     QVBoxLayout* vLayout;
 
 
-    QNetworkAccessManager* manager;
-    QString url;
-
 protected:
 protected:
-    virtual bool eventFilter(QObject* watched, QEvent* event);
+    // virtual bool eventFilter(QObject* watched, QEvent* event);
 
 
 private slots:
 private slots:
     void onFinished(QNetworkReply *reply);
     void onFinished(QNetworkReply *reply);
@@ -41,10 +45,9 @@ private slots:
 private:
 private:
     void initForm();
     void initForm();
     void initWidget();
     void initWidget();
-    void initManager();
-
-signals:
 
 
+    QString m_requestId;
+    QUrl m_currentUrl;
 };
 };
 
 
 #endif // FRMIMGSHOW_H
 #endif // FRMIMGSHOW_H

+ 77 - 1
core_form/frmsetting/frmsetting.ui

@@ -7,7 +7,7 @@
     <x>0</x>
     <x>0</x>
     <y>0</y>
     <y>0</y>
     <width>731</width>
     <width>731</width>
-    <height>439</height>
+    <height>464</height>
    </rect>
    </rect>
   </property>
   </property>
   <property name="windowTitle">
   <property name="windowTitle">
@@ -352,6 +352,82 @@
      </item>
      </item>
     </layout>
     </layout>
    </item>
    </item>
+   <item>
+    <widget class="Line" name="line3_2">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="orientation">
+      <enum>Qt::Orientation::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <item>
+      <widget class="QLabel" name="labEnableSsl_2">
+       <property name="styleSheet">
+        <string notr="true">color: rgb(255, 255, 255);</string>
+       </property>
+       <property name="text">
+        <string>自动连接</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_6">
+       <property name="orientation">
+        <enum>Qt::Orientation::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_2">
+       <property name="text">
+        <string>关</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="SwitchButton" name="schEnableSsl_2" 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>100</width>
+         <height>25</height>
+        </size>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="labEnableSslOpen_2">
+       <property name="text">
+        <string>开</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
   </layout>
   </layout>
  </widget>
  </widget>
  <customwidgets>
  <customwidgets>

+ 4 - 0
core_form/frmupload/frmupload.cpp

@@ -50,16 +50,20 @@ void FrmUpload::slot_uploadFileSec(QString url)
 
 
     if (copyType == COPY_TYPE_MARKDOWN) {
     if (copyType == COPY_TYPE_MARKDOWN) {
         clipboard->setText(QString("![](%1)").arg(url));
         clipboard->setText(QString("![](%1)").arg(url));
+        emit signal_uploadSuccess(url);
     }
     }
     if (copyType == COPY_TYPE_URL) {
     if (copyType == COPY_TYPE_URL) {
         clipboard->setText(url);
         clipboard->setText(url);
+        emit signal_uploadSuccess(url);
     }
     }
     if (copyType == COPY_TYPE_UBB) {
     if (copyType == COPY_TYPE_UBB) {
         // [IMG]https://imagehyj.oss-cn-hangzhou.aliyuncs.com/blog/logo512.png[/IMG]
         // [IMG]https://imagehyj.oss-cn-hangzhou.aliyuncs.com/blog/logo512.png[/IMG]
         clipboard->setText(QString("[IMG]%1[/IMG]").arg(url));
         clipboard->setText(QString("[IMG]%1[/IMG]").arg(url));
+        emit signal_uploadSuccess(url);
     }
     }
     if (copyType == COPY_TYPE_HTML) {
     if (copyType == COPY_TYPE_HTML) {
         clipboard->setText(QString("<img src=\"%1\"/>").arg(url));
         clipboard->setText(QString("<img src=\"%1\"/>").arg(url));
+        emit signal_uploadSuccess(url);
 
 
         // QThread::sleep(50);
         // QThread::sleep(50);
     }
     }

+ 3 - 0
core_form/frmupload/frmupload.h

@@ -70,6 +70,9 @@ private:
     // 0 md 1 url
     // 0 md 1 url
     CopyType copyType = COPY_TYPE_MARKDOWN;
     CopyType copyType = COPY_TYPE_MARKDOWN;
 
 
+signals:
+    void signal_uploadSuccess(QString url);
+
 private:
 private:
     Ui::FrmUpload *ui;
     Ui::FrmUpload *ui;
 };
 };

+ 158 - 0
core_form/panelwidget/panelwidget.cpp

@@ -0,0 +1,158 @@
+#pragma execution_character_set("utf-8")
+
+#include "panelwidget.h"
+#include "qscrollarea.h"
+#include "qframe.h"
+#include "qboxlayout.h"
+#include "qdebug.h"
+
+PanelWidget::PanelWidget(QWidget *parent) : QWidget(parent)
+{
+    scrollArea = new QScrollArea(this);
+    scrollArea->setObjectName("scrollAreaMain");
+    scrollArea->setWidgetResizable(true);
+
+    scrollAreaWidgetContents = new QWidget();
+    scrollAreaWidgetContents->setGeometry(QRect(0, 0, 100, 100));
+
+    verticalLayout = new QVBoxLayout(scrollAreaWidgetContents);
+    verticalLayout->setSpacing(0);
+    verticalLayout->setContentsMargins(0, 0, 0, 0);
+
+    frame = new QFrame(scrollAreaWidgetContents);
+    frame->setObjectName("frameMain");
+
+    gridLayout = new QGridLayout(frame);
+    gridLayout->setSpacing(0);
+    gridLayout->setContentsMargins(0, 0, 0, 0);
+
+    verticalLayout->addWidget(frame);
+    scrollArea->setWidget(scrollAreaWidgetContents);
+    frame->setStyleSheet("QFrame#frameMain{border-width:0px;}");
+
+    margin = 0;
+    space = 0;
+    autoWidth = false;
+    autoHeight = false;
+}
+
+void PanelWidget::resizeEvent(QResizeEvent *)
+{
+    scrollArea->resize(this->size());
+}
+
+QSize PanelWidget::sizeHint() const
+{
+    return QSize(300, 200);
+}
+
+QSize PanelWidget::minimumSizeHint() const
+{
+    return QSize(20, 20);
+}
+
+int PanelWidget::getMargin() const
+{
+    return this->margin;
+}
+
+int PanelWidget::getSpace() const
+{
+    return this->space;
+}
+
+bool PanelWidget::getAutoWidth() const
+{
+    return this->autoWidth;
+}
+
+bool PanelWidget::getAutoHeight() const
+{
+    return this->autoHeight;
+}
+
+QList<QWidget *> PanelWidget::getWidgets()
+{
+    return this->widgets;
+}
+
+int PanelWidget::getColumnCount()
+{
+    return this->columnCount;
+}
+
+void PanelWidget::setWidget(QList<QWidget *> widgets, int columnCount)
+{
+    this->widgets = widgets;
+    this->columnCount = columnCount;
+
+    int row = 0;
+    int column = 0;
+    int index = 0;
+
+    //先把之前的所有移除并不可见
+    foreach (QWidget *widget, widgets) {
+        gridLayout->removeWidget(widget);
+        widget->setVisible(false);
+    }
+
+    //重新添加到布局中并可见
+    foreach (QWidget *widget, widgets) {
+        gridLayout->addWidget(widget, row, column);
+        widget->setVisible(true);
+
+        column++;
+        index++;
+        if (index % columnCount == 0) {
+            row++;
+            column = 0;
+        }
+    }
+
+    row++;
+
+    //设置右边弹簧
+    if (!autoWidth) {
+        QSpacerItem *hSpacer = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
+        gridLayout->addItem(hSpacer, 0, gridLayout->columnCount());
+    }
+
+    //设置底边弹簧
+    if (!autoHeight) {
+        QSpacerItem *vSpacer = new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding);
+        gridLayout->addItem(vSpacer, row, 0);
+    }
+}
+
+void PanelWidget::setMargin(int left, int top, int right, int bottom)
+{
+    gridLayout->setContentsMargins(left, top, right, bottom);
+}
+
+void PanelWidget::setMargin(int margin)
+{
+    if (this->margin != margin) {
+        setMargin(margin, margin, margin, margin);
+    }
+}
+
+void PanelWidget::setSpace(int space)
+{
+    if (this->space != space) {
+        gridLayout->setSpacing(space);
+    }
+}
+
+void PanelWidget::setAutoWidth(bool autoWidth)
+{
+    if (this->autoWidth != autoWidth) {
+        this->autoWidth = autoWidth;
+    }
+}
+
+void PanelWidget::setAutoHeight(bool autoHeight)
+{
+    if (this->autoHeight != autoHeight) {
+        this->autoHeight = autoHeight;
+    }
+}

+ 74 - 0
core_form/panelwidget/panelwidget.h

@@ -0,0 +1,74 @@
+#ifndef PANELWIDGET_H
+#define PANELWIDGET_H
+
+#include <QWidget>
+#include <QPainterPath>
+
+class QScrollArea;
+class QFrame;
+class QVBoxLayout;
+class QGridLayout;
+
+#ifdef quc
+#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
+#include <QtDesigner/QDesignerExportWidget>
+#else
+#include <QtUiPlugin/QDesignerExportWidget>
+#endif
+
+class QDESIGNER_WIDGET_EXPORT PanelWidget : public QWidget
+#else
+class PanelWidget : public QWidget
+#endif
+
+{
+    Q_OBJECT
+    // Q_PROPERTY(int margin READ getMargin WRITE setMargin)
+    // Q_PROPERTY(int space READ getSpace WRITE setSpace)
+    // Q_PROPERTY(bool autoWidth READ getAutoWidth WRITE setAutoWidth)
+    // Q_PROPERTY(bool autoHeight READ getAutoHeight WRITE setAutoHeight)
+
+public:
+    explicit PanelWidget(QWidget *parent = 0);
+
+protected:
+    void resizeEvent(QResizeEvent *);
+
+private:
+    QScrollArea *scrollArea;            //滚动区域
+    QWidget *scrollAreaWidgetContents;  //滚动区域载体
+    QFrame *frame;                      //放置设备的框架,自动变宽变高
+    QVBoxLayout *verticalLayout;        //设备面板总布局
+    QGridLayout *gridLayout;            //设备表格布局
+
+    int margin;                         //边距
+    int space;                          //设备之间的间隔
+    bool autoWidth;                     //宽度自动拉伸
+    bool autoHeight;                    //高度自动拉伸
+
+    QList<QWidget *> widgets;           //设备面板对象集合
+    int columnCount;                    //面板列数
+
+public:
+    QSize sizeHint()                const;
+    QSize minimumSizeHint()         const;
+
+    int getMargin()                 const;
+    int getSpace()                  const;
+    bool getAutoWidth()             const;
+    bool getAutoHeight()            const;
+
+    QList<QWidget *> getWidgets();
+    int getColumnCount();
+
+public Q_SLOTS:
+    void setWidget(QList<QWidget *> widgets, int columnCount);
+    void setMargin(int left, int top, int right, int bottom);
+    void setMargin(int margin);
+    void setSpace(int space);
+    void setAutoWidth(bool autoWidth);
+    void setAutoHeight(bool autoHeight);
+
+};
+
+#endif // PANELWIDGET_H

+ 5 - 0
core_form/panelwidget/panelwidget.pri

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

+ 3 - 0
core_support/core_support.pri

@@ -4,3 +4,6 @@ include($$PWD/fileconfigdecode/fileconfigdecode.pri)
 
 
 INCLUDEPATH += $$PWD/tchttpservice
 INCLUDEPATH += $$PWD/tchttpservice
 include($$PWD/tchttpservice/tchttpservice.pri)
 include($$PWD/tchttpservice/tchttpservice.pri)
+
+INCLUDEPATH += $$PWD/urldatabase
+include($$PWD/urldatabase/urldatabase.pri)

+ 84 - 27
core_support/tchttpservice/tchttpservice.cpp

@@ -32,18 +32,31 @@ void TCHttpService::apiLogin()
 
 
     QNetworkReply* reply = nullptr;
     QNetworkReply* reply = nullptr;
 
 
-   QNetworkRequest request(url);
+    QNetworkRequest request(url);
     for (auto ite = headers.constBegin(); ite != headers.constEnd(); ite++){
     for (auto ite = headers.constBegin(); ite != headers.constEnd(); ite++){
        request.setRawHeader(ite.key().toUtf8(), ite.value().toUtf8());
        request.setRawHeader(ite.key().toUtf8(), ite.value().toUtf8());
     }
     }
-   reply = m_manager.post(request, jsonData);
+    reply = m_manager.post(request, jsonData);
 
 
-       QObject::connect(reply, &QNetworkReply::finished, [this, reply]() {
+    QObject::connect(reply, &QNetworkReply::finished, [this, reply]() {
+
+        QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
+        if (jsonDoc.isEmpty())
+            return;
+        QJsonObject jsonObj = jsonDoc.object();
+        int code = jsonObj["code"].toInt();
+        if (code == 0) {
+            this->m_token = jsonObj["token"].toString();
+            qDebug() << this->m_token;
+            m_isOnline = true;
+            emit signal_loginSuc();
+        }
+
+    });
 
 
-       emit requestFinished(reply, "login");
-   });
 }
 }
 
 
+#if 0
 void TCHttpService::apiMyfileCount()
 void TCHttpService::apiMyfileCount()
 {
 {
 
 
@@ -155,7 +168,7 @@ void TCHttpService::apiMd5(const QString& filePath)
         emit requestFinished(reply, "md5");
         emit requestFinished(reply, "md5");
     });
     });
 }
 }
-
+#endif
 void TCHttpService::apiUpload(const QString &filePath)
 void TCHttpService::apiUpload(const QString &filePath)
 {
 {
 
 
@@ -229,10 +242,14 @@ void TCHttpService::apiUpload(const QString &filePath)
     connect(reply, &QNetworkReply::finished, this, [=]() {
     connect(reply, &QNetworkReply::finished, this, [=]() {
         if (reply->error() == QNetworkReply::NoError) {
         if (reply->error() == QNetworkReply::NoError) {
             qDebug() << "上传成功:";
             qDebug() << "上传成功:";
-            apiMyfileCount();
+            QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll());
+            QJsonObject jsonObj = jsonDoc.object();
+            QString fileUrl = jsonObj["url"].toString();
+            emit signal_uploadFileSec(fileUrl);
         } else {
         } else {
             qDebug() << "上传失败:" << reply->errorString();
             qDebug() << "上传失败:" << reply->errorString();
         }
         }
+
         reply->deleteLater();
         reply->deleteLater();
         multiPart->deleteLater();
         multiPart->deleteLater();
     });
     });
@@ -272,6 +289,7 @@ void TCHttpService::setConfiguration(QString userName, QString firstPwd, QString
     this->m_domain = domain;
     this->m_domain = domain;
     this->m_userName = userName;
     this->m_userName = userName;
     this->m_firstPwd = firstPwd;
     this->m_firstPwd = firstPwd;
+#if 0
     connect(this, &TCHttpService::requestFinished, [this](QNetworkReply* reply, QString api){
     connect(this, &TCHttpService::requestFinished, [this](QNetworkReply* reply, QString api){
         QByteArray rawData = reply->readAll();
         QByteArray rawData = reply->readAll();
         if (api == "login") {
         if (api == "login") {
@@ -284,11 +302,13 @@ void TCHttpService::setConfiguration(QString userName, QString firstPwd, QString
             if (code == 0) {
             if (code == 0) {
                 this->m_token = jsonObj["token"].toString();
                 this->m_token = jsonObj["token"].toString();
                 qDebug() << this->m_token;
                 qDebug() << this->m_token;
-
-                apiMyfileCount();
+                 m_isOnline = true;
+                emit signal_loginSuc();
+                // apiMyfileCount();
 
 
             }
             }
         }
         }
+#if 0
         if (api == "myfilecount") {
         if (api == "myfilecount") {
             QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData);
             QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData);
             if (jsonDoc.isEmpty())
             if (jsonDoc.isEmpty())
@@ -309,6 +329,7 @@ void TCHttpService::setConfiguration(QString userName, QString firstPwd, QString
 
 
             }
             }
         }
         }
+
         if (api == "myfilenormal") {
         if (api == "myfilenormal") {
             static int loginCnt = 0;
             static int loginCnt = 0;
 
 
@@ -356,14 +377,14 @@ void TCHttpService::setConfiguration(QString userName, QString firstPwd, QString
                 qDebug() << "fileMap size:" << m_fileMap.size();
                 qDebug() << "fileMap size:" << m_fileMap.size();
 #endif
 #endif
             }
             }
-            if (!m_isOnline) {
-                loginCnt++;
-                qDebug() << "loginCnt:" << loginCnt;
-                if (loginCnt == m_total/10+1) {
-                    m_isOnline = true;
-                    qDebug() << "login success";
-                }
-            }
+            // if (!m_isOnline) {
+            //     loginCnt++;
+            //     qDebug() << "loginCnt:" << loginCnt;
+            //     if (loginCnt == m_total/10+1) {
+            //         m_isOnline = true;
+            //         qDebug() << "login success";
+            //     }
+            // }
 
 
         }
         }
         // if (api == "upload") {
         // if (api == "upload") {
@@ -376,8 +397,10 @@ void TCHttpService::setConfiguration(QString userName, QString firstPwd, QString
         //     if (code == 0)
         //     if (code == 0)
         //         this->apiMyfileCount();
         //         this->apiMyfileCount();
         // }
         // }
+#endif
         reply->deleteLater();
         reply->deleteLater();
     });
     });
+#endif
     apiLogin();
     apiLogin();
 }
 }
 
 
@@ -396,6 +419,33 @@ void TCHttpService::setUploadNum(int nb)
     this->m_uploadNum = nb;
     this->m_uploadNum = nb;
 }
 }
 
 
+void TCHttpService::downloadImage(const QString &requestId, const QUrl &imageUrl)
+{
+    QNetworkRequest request(imageUrl);
+    QNetworkReply* reply = m_manager.get(request);
+
+    connect(reply, &QNetworkReply::finished, [this, reply](){
+
+        QString requestId = m_pendingRequests.take(reply);
+
+        if (reply->error() != QNetworkReply::NoError) {
+            emit signal_downloadFailed(requestId, reply->errorString());
+        }
+        else {
+            QPixmap pixmap;
+            if (pixmap.loadFromData(reply->readAll())) {
+                emit signal_imageDownloaded(requestId, pixmap);
+            }
+            else {
+                emit signal_downloadFailed(requestId, "Failed to load image data");
+            }
+        }
+
+        reply->deleteLater();
+    });
+    m_pendingRequests[reply] = requestId;
+}
+
 QUrl TCHttpService::encodeUrl(QString urlStr, QMap<QString, QString> params)
 QUrl TCHttpService::encodeUrl(QString urlStr, QMap<QString, QString> params)
 {
 {
     QUrlQuery query;
     QUrlQuery query;
@@ -409,20 +459,27 @@ QUrl TCHttpService::encodeUrl(QString urlStr, QMap<QString, QString> params)
     return url;
     return url;
 }
 }
 
 
-
-void TCHttpService::updateFileMap(QJsonObject jsonObj)
+TCHttpService::TCHttpService(QObject *parent) : QObject(parent)
 {
 {
-    // QString fileMD5 = jsonObj["md5"].toString();
-    // QString fileUrl = jsonObj["http"].toString();
-
-    // QMap<QString, file_info_t>::iterator ite = m_fileMap.begin();
-    // if (ite != m_fileMap.end())
-    //     return;
 
 
-    // m_fileMap.insert(fileMD5, fileUrl);
 }
 }
 
 
-TCHttpService::TCHttpService(QObject *parent) : QObject(parent)
+void TCHttpService::slot_downloadFinished(QNetworkReply *reply)
 {
 {
+    QString requestId = m_pendingRequests.take(reply);
+
+    if (reply->error() != QNetworkReply::NoError) {
+        emit signal_downloadFailed(requestId, reply->errorString());
+    }
+    else {
+        QPixmap pixmap;
+        if (pixmap.loadFromData(reply->readAll())) {
+            emit signal_imageDownloaded(requestId, pixmap);
+        }
+        else {
+            emit signal_downloadFailed(requestId, "Failed to load image data");
+        }
+    }
 
 
+    reply->deleteLater();
 }
 }

+ 14 - 2
core_support/tchttpservice/tchttpservice.h

@@ -14,9 +14,11 @@
 #include <QJsonArray>
 #include <QJsonArray>
 #include <QFile>
 #include <QFile>
 #include <QFileInfo>
 #include <QFileInfo>
+#include <QPixmap>
 #include <QHttpMultiPart>
 #include <QHttpMultiPart>
 #include <QHttpPart>
 #include <QHttpPart>
 #include <QHttpMultiPart>
 #include <QHttpMultiPart>
+#include <QHash>
 
 
 class TCHttpService : public QObject
 class TCHttpService : public QObject
 {
 {
@@ -34,9 +36,11 @@ public:
     static TCHttpService* getInstance();
     static TCHttpService* getInstance();
 
 
     void apiLogin();
     void apiLogin();
+#if 0
     void apiMyfileCount();
     void apiMyfileCount();
     void apiMyfileNormal(int start, int count);
     void apiMyfileNormal(int start, int count);
     void apiMd5(const QString& filePath);
     void apiMd5(const QString& filePath);
+#endif
     void apiUpload(const QString& filePath);
     void apiUpload(const QString& filePath);
     void apiSharePicShare(const QString& fileName, const QString& md5);
     void apiSharePicShare(const QString& fileName, const QString& md5);
     void setConfiguration(QString userName, QString firstPwd, QString domain);
     void setConfiguration(QString userName, QString firstPwd, QString domain);
@@ -44,16 +48,20 @@ public:
     bool getOnlineState();
     bool getOnlineState();
     void setUploadNum(int nb);
     void setUploadNum(int nb);
 
 
+    void downloadImage(const QString& requestId, const QUrl& imageUrl);
+
 private:
 private:
 
 
     QUrl encodeUrl(QString url, QMap<QString, QString> params);
     QUrl encodeUrl(QString url, QMap<QString, QString> params);
-    void updateFileMap(QJsonObject jsonObj);
+
 signals:
 signals:
     void signal_loginSuc();
     void signal_loginSuc();
-    void signal_uploadSuc();
     void signal_shareSuc();
     void signal_shareSuc();
     void signal_uploadFileSec(QString url);
     void signal_uploadFileSec(QString url);
     void requestFinished(QNetworkReply* reply, QString api);
     void requestFinished(QNetworkReply* reply, QString api);
+
+    void signal_imageDownloaded(const QString& requestId, const QPixmap& pixmap);
+    void signal_downloadFailed(const QString& requestId, const QString& error);
 private:
 private:
     explicit TCHttpService(QObject *parent = nullptr);
     explicit TCHttpService(QObject *parent = nullptr);
 
 
@@ -72,6 +80,10 @@ private:
 
 
     bool m_uploadNum = 0;
     bool m_uploadNum = 0;
 
 
+    QHash<QNetworkReply*, QString> m_pendingRequests;
+
+private slots:
+    void slot_downloadFinished(QNetworkReply* reply);
 };
 };
 
 
 #endif // TCHTTPSERVICE_H
 #endif // TCHTTPSERVICE_H

+ 217 - 0
core_support/urldatabase/urldatabase.cpp

@@ -0,0 +1,217 @@
+#include "urldatabase.h"
+
+ImageUrlDatabase::ImageUrlDatabase(QObject *parent) : QObject(parent)
+{
+}
+
+ImageUrlDatabase::~ImageUrlDatabase()
+{
+    if (m_db.isOpen()) {
+        m_db.close();
+    }
+}
+
+bool ImageUrlDatabase::openDatabase(const QString &path)
+{
+    m_db = QSqlDatabase::addDatabase("QSQLITE");
+    m_db.setDatabaseName(path);
+
+    if (!m_db.open()) {
+        qWarning() << "Failed to open database:" << m_db.lastError().text();
+        return false;
+    }
+
+    // 创建表结构
+    QSqlQuery query;
+
+    // 创建用户表
+    if (!query.exec("CREATE TABLE IF NOT EXISTS users ("
+                    "user_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+                    "username TEXT NOT NULL UNIQUE, "
+                    "created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)")) {
+        qWarning() << "Failed to create users table:" << query.lastError().text();
+        return false;
+    }
+
+    // 创建服务器表
+    if (!query.exec("CREATE TABLE IF NOT EXISTS servers ("
+                    "server_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+                    "domain TEXT NOT NULL UNIQUE, "
+                    "created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)")) {
+        qWarning() << "Failed to create servers table:" << query.lastError().text();
+        return false;
+    }
+
+    // 创建图片URL表
+    if (!query.exec("CREATE TABLE IF NOT EXISTS image_urls ("
+                    "url_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+                    "user_id INTEGER NOT NULL, "
+                    "server_id INTEGER NOT NULL, "
+                    "image_url TEXT NOT NULL, "
+                    "last_accessed TIMESTAMP, "
+                    "created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "
+                    "FOREIGN KEY (user_id) REFERENCES users(user_id), "
+                    "FOREIGN KEY (server_id) REFERENCES servers(server_id), "
+                    "UNIQUE(user_id, server_id, image_url))")) {
+        qWarning() << "Failed to create image_urls table:" << query.lastError().text();
+        return false;
+    }
+
+    // 创建索引
+    query.exec("CREATE INDEX IF NOT EXISTS idx_image_user ON image_urls(user_id)");
+    query.exec("CREATE INDEX IF NOT EXISTS idx_image_server ON image_urls(server_id)");
+
+    return true;
+}
+
+int ImageUrlDatabase::addUser(const QString &username)
+{
+    QSqlQuery query;
+    query.prepare("INSERT OR IGNORE INTO users (username) VALUES (?)");
+    query.addBindValue(username);
+
+    if (!query.exec()) {
+        qWarning() << "Failed to add user:" << query.lastError().text();
+        return -1;
+    }
+
+    // 获取用户ID
+    return getUserId(username);
+}
+
+int ImageUrlDatabase::getUserId(const QString &username)
+{
+    QSqlQuery query;
+    query.prepare("SELECT user_id FROM users WHERE username = ?");
+    query.addBindValue(username);
+
+    if (!query.exec() || !query.next()) {
+        return -1;
+    }
+
+    return query.value(0).toInt();
+}
+
+int ImageUrlDatabase::addServer(const QString &domain)
+{
+    QSqlQuery query;
+    query.prepare("INSERT OR IGNORE INTO servers (domain) VALUES (?)");
+    query.addBindValue(domain);
+
+    if (!query.exec()) {
+        qWarning() << "Failed to add server:" << query.lastError().text();
+        return -1;
+    }
+
+    // 获取服务器ID
+    return getServerId(domain);
+}
+
+int ImageUrlDatabase::getServerId(const QString &domain)
+{
+    QSqlQuery query;
+    query.prepare("SELECT server_id FROM servers WHERE domain = ?");
+    query.addBindValue(domain);
+
+    if (!query.exec() || !query.next()) {
+        return -1;
+    }
+
+    return query.value(0).toInt();
+}
+
+bool ImageUrlDatabase::addImageUrl(const QString &username, const QString &domain, const QString &imageUrl)
+{
+    int userId = addUser(username);
+    if (userId == -1) return false;
+
+    int serverId = addServer(domain);
+    if (serverId == -1) return false;
+
+    QSqlQuery query;
+    query.prepare("INSERT OR REPLACE INTO image_urls (user_id, server_id, image_url, last_accessed) "
+                  "VALUES (?, ?, ?, datetime('now'))");
+    query.addBindValue(userId);
+    query.addBindValue(serverId);
+    query.addBindValue(imageUrl);
+
+    if (!query.exec()) {
+        qWarning() << "Failed to add image URL:" << query.lastError().text();
+        return false;
+    }
+
+    return true;
+}
+
+QList<QString> ImageUrlDatabase::getUserImages(const QString &username)
+{
+    QList<QString> result;
+    int userId = getUserId(username);
+
+    if (userId == -1) return result;
+
+    QSqlQuery query;
+    query.prepare("SELECT i.image_url FROM image_urls i "
+                  "WHERE i.user_id = ? "
+                  "ORDER BY i.last_accessed DESC");
+    query.addBindValue(userId);
+
+    if (!query.exec()) {
+        qWarning() << "Failed to get user images:" << query.lastError().text();
+        return result;
+    }
+
+    while (query.next()) {
+        result.append(query.value(0).toString());
+    }
+
+    return result;
+}
+
+QList<QString> ImageUrlDatabase::getServerImages(const QString &domain)
+{
+    QList<QString> result;
+    int serverId = getServerId(domain);
+
+    if (serverId == -1) return result;
+
+    QSqlQuery query;
+    query.prepare("SELECT i.image_url FROM image_urls i "
+                  "WHERE i.server_id = ? "
+                  "ORDER BY i.last_accessed DESC");
+    query.addBindValue(serverId);
+
+    if (!query.exec()) {
+        qWarning() << "Failed to get server images:" << query.lastError().text();
+        return result;
+    }
+
+    while (query.next()) {
+        result.append(query.value(0).toString());
+    }
+
+    return result;
+}
+
+bool ImageUrlDatabase::updateLastAccessed(const QString &username, const QString &domain, const QString &imageUrl)
+{
+    int userId = getUserId(username);
+    if (userId == -1) return false;
+
+    int serverId = getServerId(domain);
+    if (serverId == -1) return false;
+
+    QSqlQuery query;
+    query.prepare("UPDATE image_urls SET last_accessed = datetime('now') "
+                  "WHERE user_id = ? AND server_id = ? AND image_url = ?");
+    query.addBindValue(userId);
+    query.addBindValue(serverId);
+    query.addBindValue(imageUrl);
+
+    if (!query.exec()) {
+        qWarning() << "Failed to update last accessed time:" << query.lastError().text();
+        return false;
+    }
+
+    return query.numRowsAffected() > 0;
+}

+ 39 - 0
core_support/urldatabase/urldatabase.h

@@ -0,0 +1,39 @@
+#ifndef URLDATABASE_H
+#define URLDATABASE_H
+
+#include <QObject>
+#include <QSqlDatabase>
+#include <QSqlQuery>
+#include <QSqlError>
+#include <QDateTime>
+
+class ImageUrlDatabase : public QObject
+{
+    Q_OBJECT
+public:
+    explicit ImageUrlDatabase(QObject *parent = nullptr);
+    ~ImageUrlDatabase();
+
+    bool openDatabase(const QString &path);
+
+    // 用户操作
+    int addUser(const QString &username);
+
+    // 服务器操作
+    int addServer(const QString &domain);
+
+    // 图片URL操作
+    bool addImageUrl(const QString &username, const QString &domain, const QString &imageUrl);
+    QList<QString> getUserImages(const QString &username);
+    QList<QString> getServerImages(const QString &domain);
+    bool updateLastAccessed(const QString &username, const QString &domain, const QString &imageUrl);
+
+private:
+    QSqlDatabase m_db;
+
+    // 内部辅助方法
+    int getUserId(const QString &username);
+    int getServerId(const QString &domain);
+};
+
+#endif // URLDATABASE_H

+ 5 - 0
core_support/urldatabase/urldatabase.pri

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

+ 1 - 0
image.qrc

@@ -13,5 +13,6 @@
         <file>qrc/image/delete_red.png</file>
         <file>qrc/image/delete_red.png</file>
         <file>qrc/image/delete_white.png</file>
         <file>qrc/image/delete_white.png</file>
         <file>qrc/image/copy_blue.png</file>
         <file>qrc/image/copy_blue.png</file>
+        <file>qrc/image/icon200.png</file>
     </qresource>
     </qresource>
 </RCC>
 </RCC>

+ 2 - 2
picpanel.pro

@@ -1,4 +1,4 @@
-QT       += core gui network
+QT       += core gui network sql
 
 
 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 
 
@@ -22,7 +22,7 @@ INCLUDEPATH += $$PWD
 INCLUDEPATH += $$PWD/core_form
 INCLUDEPATH += $$PWD/core_form
 INCLUDEPATH += $$PWD/core_ui
 INCLUDEPATH += $$PWD/core_ui
 INCLUDEPATH += $$PWD/core_support
 INCLUDEPATH += $$PWD/core_support
-#include($$PWD/core_qui/core_qui.pri)
+include($$PWD/core_qui/core_qui.pri)
 include($$PWD/core_form/core_form.pri)
 include($$PWD/core_form/core_form.pri)
 include($$PWD/core_ui/core_ui.pri)
 include($$PWD/core_ui/core_ui.pri)
 include($$PWD/core_support/core_support.pri)
 include($$PWD/core_support/core_support.pri)

+ 15 - 262
picpanel.pro.user

@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 14.0.2, 2025-03-25T02:39:05. -->
+<!-- Written by QtCreator 14.0.2, 2025-03-25T18:34:03. -->
 <qtcreator>
 <qtcreator>
  <data>
  <data>
   <variable>EnvironmentId</variable>
   <variable>EnvironmentId</variable>
-  <value type="QByteArray">{4f2ec396-c2e0-4f3d-a369-5968ecaf5cee}</value>
+  <value type="QByteArray">{631b5895-04c2-4f08-83d2-9e1277f189a1}</value>
  </data>
  </data>
  <data>
  <data>
   <variable>ProjectExplorer.Project.ActiveTarget</variable>
   <variable>ProjectExplorer.Project.ActiveTarget</variable>
@@ -41,7 +41,7 @@
    <value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
    <value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
    <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
    <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
    <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
    <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
-   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
    <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
    <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
    <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
    <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
    <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
    <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
@@ -74,15 +74,11 @@
    <valuelist type="QVariantList" key="AutoTest.PathFilters"/>
    <valuelist type="QVariantList" key="AutoTest.PathFilters"/>
    <value type="int" key="AutoTest.RunAfterBuild">0</value>
    <value type="int" key="AutoTest.RunAfterBuild">0</value>
    <value type="bool" key="AutoTest.UseGlobal">true</value>
    <value type="bool" key="AutoTest.UseGlobal">true</value>
-   <valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey">
-    <value type="QString">-fno-delayed-template-parsing</value>
-   </valuelist>
-   <value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
    <valuemap type="QVariantMap" key="ClangTools">
    <valuemap type="QVariantMap" key="ClangTools">
     <value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
     <value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
     <value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
     <value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
     <value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
     <value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
-    <value type="int" key="ClangTools.ParallelJobs">16</value>
+    <value type="int" key="ClangTools.ParallelJobs">12</value>
     <value type="bool" key="ClangTools.PreferConfigFile">true</value>
     <value type="bool" key="ClangTools.PreferConfigFile">true</value>
     <valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
     <valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
     <valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
     <valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
@@ -98,13 +94,13 @@
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.7.3 MinGW 64-bit</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.7.3 MinGW 64-bit</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.7.3 MinGW 64-bit</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.7.3 MinGW 64-bit</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.673.win64_mingw_kit</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.673.win64_mingw_kit</value>
-   <value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</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.ActiveDeployConfiguration">0</value>
    <value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
    <value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
     <value type="int" key="EnableQmlDebugging">0</value>
     <value type="int" key="EnableQmlDebugging">0</value>
-    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:\Workspaces\picpanel\build\Desktop_Qt_6_7_3_MinGW_64_bit-Debug</value>
-    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">D:/Workspaces/picpanel/build/Desktop_Qt_6_7_3_MinGW_64_bit-Debug</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">E:\picpanel\build\Desktop_Qt_6_7_3_MinGW_64_bit-Debug</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">E:/picpanel/build/Desktop_Qt_6_7_3_MinGW_64_bit-Debug</value>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
@@ -142,8 +138,8 @@
     <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
     <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
    </valuemap>
    </valuemap>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
-    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:\Workspaces\picpanel\build\Desktop_Qt_6_7_3_MinGW_64_bit-Release</value>
-    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">D:/Workspaces/picpanel/build/Desktop_Qt_6_7_3_MinGW_64_bit-Release</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">E:\picpanel\build\Desktop_Qt_6_7_3_MinGW_64_bit-Release</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">E:/picpanel/build/Desktop_Qt_6_7_3_MinGW_64_bit-Release</value>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
@@ -183,8 +179,8 @@
    </valuemap>
    </valuemap>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
     <value type="int" key="EnableQmlDebugging">0</value>
     <value type="int" key="EnableQmlDebugging">0</value>
-    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:\Workspaces\picpanel\build\Desktop_Qt_6_7_3_MinGW_64_bit-Profile</value>
-    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">D:/Workspaces/picpanel/build/Desktop_Qt_6_7_3_MinGW_64_bit-Profile</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">E:\picpanel\build\Desktop_Qt_6_7_3_MinGW_64_bit-Profile</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">E:/picpanel/build/Desktop_Qt_6_7_3_MinGW_64_bit-Profile</value>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
@@ -249,263 +245,20 @@
     <value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
     <value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
     <value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph &quot;dwarf,4096&quot; -F 250</value>
     <value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph &quot;dwarf,4096&quot; -F 250</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
-    <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="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:E:/picpanel/picpanel.pro</value>
+    <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">E:/picpanel/picpanel.pro</value>
     <value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
     <value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
     <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
     <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
     <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
     <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
     <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
     <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
-    <value type="QString" key="RunConfiguration.WorkingDirectory.default">D:/Workspaces/picpanel/build/Desktop_Qt_6_7_3_MinGW_64_bit-Release</value>
+    <value type="QString" key="RunConfiguration.WorkingDirectory.default">E:/picpanel/build/Desktop_Qt_6_7_3_MinGW_64_bit-Debug</value>
    </valuemap>
    </valuemap>
    <value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
    <value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
   </valuemap>
   </valuemap>
  </data>
  </data>
- <data>
-  <variable>ProjectExplorer.Project.Target.1</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"></value>
-   </valuemap>
-   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
-  </valuemap>
- </data>
  <data>
  <data>
   <variable>ProjectExplorer.Project.TargetCount</variable>
   <variable>ProjectExplorer.Project.TargetCount</variable>
-  <value type="qlonglong">2</value>
+  <value type="qlonglong">1</value>
  </data>
  </data>
  <data>
  <data>
   <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
   <variable>ProjectExplorer.Project.Updater.FileVersion</variable>

BIN
qrc/image/icon.png


BIN
qrc/image/icon200.png


+ 59 - 12
widget.cpp

@@ -10,6 +10,7 @@ Widget::Widget(QWidget *parent)
     initWidgetForm();
     initWidgetForm();
     initWidget();
     initWidget();
     initSignalSlot();
     initSignalSlot();
+    initTrayApp();
     // this->btnPageUpload->setChecked(true);
     // this->btnPageUpload->setChecked(true);
     // this->btnPageUpload->setStyleSheet("{border: none;border-right: 4px solid #409EFF;color: #409EFF;}");
     // this->btnPageUpload->setStyleSheet("{border: none;border-right: 4px solid #409EFF;color: #409EFF;}");
 }
 }
@@ -127,15 +128,6 @@ bool Widget::eventFilter(QObject *watched, QEvent *event)
 
 
 void Widget::paintEvent(__attribute__((unused))QPaintEvent *event)
 void Widget::paintEvent(__attribute__((unused))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;
     QStyleOption opt;
 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
     opt.init(this);
     opt.init(this);
@@ -166,7 +158,12 @@ void Widget::initWidgetForm()
     IconHelper::setIcon(ui->btnMin, QString("F068").toInt(nullptr, 16), 16);
     IconHelper::setIcon(ui->btnMin, QString("F068").toInt(nullptr, 16), 16);
     IconHelper::setIcon(ui->btnClose, QString("F00D").toInt(nullptr, 16), 16);
     IconHelper::setIcon(ui->btnClose, QString("F00D").toInt(nullptr, 16), 16);
 
 
-    ui->labTitle->setText("PicPanel");
+    QString version = QString("%1-%2.%3").arg("PicPanel").arg(VERSION_MAJ).arg(VERSION_MIN);
+
+    if (VERSION_BATE)
+        version += "-beta";
+
+    ui->labTitle->setText(version);
 
 
 }
 }
 
 
@@ -206,12 +203,14 @@ void Widget::initSignalSlot()
         b->installEventFilter(this);
         b->installEventFilter(this);
     }
     }
 
 
+    connect(TCHttpService::getInstance(), &TCHttpService::signal_loginSuc, this, &Widget::slot_loginSec);
+    connect(frmupload, &FrmUpload::signal_uploadSuccess, this, &Widget::slot_uploadSuccess);
 }
 }
 
 
 void Widget::initLeftMenu()
 void Widget::initLeftMenu()
 {
 {
-    frmupload = new FrmUpload;
-    frmalbum = new FrmAlbum;
+    frmupload = new FrmUpload(this);
+    frmalbum = new FrmAlbum(this);
     frmsetting = new FrmSetting(this);
     frmsetting = new FrmSetting(this);
 
 
     ui->frmTop->setPalette(QPalette(QColor(63, 60, 55)));
     ui->frmTop->setPalette(QPalette(QColor(63, 60, 55)));
@@ -289,7 +288,45 @@ void Widget::initLeftMenu()
     ui->frame->setLayout(frameLayout);
     ui->frame->setLayout(frameLayout);
 }
 }
 
 
+void Widget::initTrayApp()
+{
+    trayIcon = new QSystemTrayIcon;
+    trayIcon->setIcon(QIcon(":/qrc/image/icon.png"));
+    trayIcon->setToolTip("PicPanel");
+
+    QMenu* trayMenu = new QMenu();
+    QAction* exitAction = new QAction("Exit");
+    connect(exitAction, &QAction::triggered, qApp, &QApplication::quit);
+    trayIcon->setContextMenu(trayMenu);
+
+    trayIcon->show();
+}
+
+void Widget::showNotification(QString title, QString content)
+{
+    qDebug() << "showNotification";
+    trayIcon->showMessage(title, content, QIcon(":/qrc/image/icon200.png"));
+    // NOTIFYICONDATA nid = {0};
+    // nid.cbSize = sizeof(NOTIFYICONDATA);
+    // // nid.hWnd = (HWND)QGuiApplication::primaryScreen();
+    // nid.hWnd = reinterpret_cast<HWND>(this->winId());
+    // nid.uFlags = NIF_INFO | NIF_ICON | NIF_MESSAGE;
+
+    // QString iconPath = "./qrc/image/icon.png";
+    // HICON hIcon = (HICON)LoadImage(NULL, iconPath.toStdWString().c_str(), IMAGE_ICON,
+    //                                 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);
+    // nid.hIcon = hIcon;
+
+    // std::wstring wtext = content.toStdWString();
+    // LPCWSTR lpText = wtext.c_str();
+
+    // wcscpy_s(nid.szTip, lpText);
 
 
+    // Shell_NotifyIcon(NIM_MODIFY, &nid);
+    // Shell_NotifyIcon(NIM_ADD, &nid);
+
+    // DestroyIcon(hIcon);
+}
 
 
 void Widget::on_btnClose_clicked()
 void Widget::on_btnClose_clicked()
 {
 {
@@ -369,3 +406,13 @@ void Widget::actPrivateLicSlot()
                              "4.信息安全<br><br>"
                              "4.信息安全<br><br>"
                              "a)本软件不会收集您的个人信息、密钥信息等隐私信息,所收集的信息仅仅作为改善软件、优化体验、了解软件日活等用途。");
                              "a)本软件不会收集您的个人信息、密钥信息等隐私信息,所收集的信息仅仅作为改善软件、优化体验、了解软件日活等用途。");
 }
 }
+
+void Widget::slot_loginSec()
+{
+    showNotification("登录成功", "登录成功");
+}
+
+void Widget::slot_uploadSuccess(QString url)
+{
+    showNotification("上传成功", url);
+}

+ 20 - 2
widget.h

@@ -12,12 +12,22 @@
 #include <QEvent>
 #include <QEvent>
 #include <QPaintEvent>
 #include <QPaintEvent>
 #include <QMessageBox>
 #include <QMessageBox>
+#include <QSystemTrayIcon>
+#include <QMenu>
+#include <QAction>
+#include <windows.h>
+#include <QIcon>
 #include "fileconfigdecode.h"
 #include "fileconfigdecode.h"
 #include "frmalbum.h"
 #include "frmalbum.h"
 #include "frmsetting.h"
 #include "frmsetting.h"
 #include "frmupload.h"
 #include "frmupload.h"
 #include "iconhelper.h"
 #include "iconhelper.h"
 
 
+#define VERSION_MAJ "2"
+#define VERSION_MIN "0"
+
+#define VERSION_BATE 1
+
 class QPushButton;
 class QPushButton;
 
 
 QT_BEGIN_NAMESPACE
 QT_BEGIN_NAMESPACE
@@ -43,17 +53,23 @@ private slots:
     void on_btnClose_clicked();
     void on_btnClose_clicked();
 
 
     void on_btnMin_clicked();
     void on_btnMin_clicked();
-
-private slots:
     void pageChangeSlot();
     void pageChangeSlot();
     void actAboutSlot();
     void actAboutSlot();
     void actRcodeSlot();
     void actRcodeSlot();
     void actPrivateLicSlot();
     void actPrivateLicSlot();
+
+    void slot_loginSec();
+
+public slots:
+    void slot_uploadSuccess(QString url);
 private:
 private:
     void initWidgetForm();
     void initWidgetForm();
     void initWidget();
     void initWidget();
     void initSignalSlot();
     void initSignalSlot();
     void initLeftMenu();
     void initLeftMenu();
+    void initTrayApp();
+
+    void showNotification(QString title, QString content);
 
 
 private:
 private:
     Ui::Widget *ui;
     Ui::Widget *ui;
@@ -71,6 +87,8 @@ private:
     QAction* actRcode;
     QAction* actRcode;
     QAction* actPrivateLic;
     QAction* actPrivateLic;
 
 
+    QSystemTrayIcon* trayIcon;
+
     FileConfigDecode* fileConfig;
     FileConfigDecode* fileConfig;
 
 
 };
 };