Compare commits
2 Commits
9ea3b2c30b
...
3f30e4ed4d
Author | SHA1 | Date |
---|---|---|
wuyize | 3f30e4ed4d | |
wuyize | ec46100322 |
|
@ -26,22 +26,6 @@ FluWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: tool_bar
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 140
|
|
||||||
|
|
||||||
height: 44
|
|
||||||
|
|
||||||
layoutDirection: Qt.RightToLeft
|
|
||||||
|
|
||||||
// Rectangle{
|
|
||||||
// anchors.fill: parent
|
|
||||||
// color: "red"
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
@ -101,10 +85,7 @@ FluWindow {
|
||||||
onReady: {
|
onReady: {
|
||||||
setTitleBarItem(title_bar)
|
setTitleBarItem(title_bar)
|
||||||
moveWindowToDesktopCenter()
|
moveWindowToDesktopCenter()
|
||||||
setHitTestVisible(title_bar.minimizeButton())
|
title_bar.setHitTestVisibleItems(framless_helper)
|
||||||
setHitTestVisible(title_bar.maximizeButton())
|
|
||||||
setHitTestVisible(title_bar.closeButton())
|
|
||||||
setHitTestVisible(title_bar.transferButton())
|
|
||||||
title_bar.maximizeButton.visible = true
|
title_bar.maximizeButton.visible = true
|
||||||
// window.backgroundVisible = false
|
// window.backgroundVisible = false
|
||||||
window.show()
|
window.show()
|
||||||
|
|
|
@ -110,6 +110,15 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FluIconButton {
|
||||||
|
id: btn_note
|
||||||
|
height: 32
|
||||||
|
width: 32
|
||||||
|
Layout.rightMargin: 10
|
||||||
|
iconSource: FluentIcons.PenPalette
|
||||||
|
iconSize: 14
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
Layout.margins: {
|
Layout.margins: {
|
||||||
right: 10
|
right: 10
|
||||||
|
@ -204,7 +213,10 @@ Rectangle {
|
||||||
return btn_close
|
return btn_close
|
||||||
}
|
}
|
||||||
|
|
||||||
function transferButton() {
|
function setHitTestVisibleItems(frameless_helper) {
|
||||||
return btn_transfer
|
frameless_helper.setHitTestVisible(btn_minimize)
|
||||||
|
frameless_helper.setHitTestVisible(btn_maximize)
|
||||||
|
frameless_helper.setHitTestVisible(btn_close)
|
||||||
|
frameless_helper.setHitTestVisible(btn_transfer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,52 +16,29 @@ Popup {
|
||||||
FluShadow {}
|
FluShadow {}
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: Item {
|
contentItem: FluScrollablePage {
|
||||||
anchors.top: parent.top
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: 10
|
||||||
ListModel //模型-提供数据
|
|
||||||
{
|
|
||||||
id: itemModel
|
|
||||||
ListElement {
|
|
||||||
|
|
||||||
name: "Apple"
|
|
||||||
progressValue: 0.1
|
|
||||||
}
|
|
||||||
ListElement {
|
|
||||||
name: "Orange"
|
|
||||||
progressValue: 1
|
|
||||||
}
|
|
||||||
ListElement {
|
|
||||||
name: "Banana"
|
|
||||||
progressValue: 0.6
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component //委托-提供一个展示数据的示例(如何展示一个模型中的数据)
|
|
||||||
{
|
|
||||||
id: itemDelegate
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.bottomMargin: -10
|
||||||
|
Repeater {
|
||||||
|
model: FileTransferListModel
|
||||||
|
delegate: ColumnLayout {
|
||||||
|
Layout.bottomMargin: 10
|
||||||
spacing: 10
|
spacing: 10
|
||||||
width: parent.width
|
width: parent.width
|
||||||
Text {
|
Text {
|
||||||
Layout.topMargin: 10
|
|
||||||
text: name
|
text: name
|
||||||
}
|
}
|
||||||
|
|
||||||
FluProgressBar {
|
FluProgressBar {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
progress: progressValue
|
progress: completedSize / totalSize
|
||||||
indeterminate: false
|
indeterminate: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView //视图-设置委托和模型,根据委托提供的展示方式展示模型提供的数据
|
|
||||||
{
|
|
||||||
anchors.fill: parent
|
|
||||||
model: itemModel
|
|
||||||
delegate: itemDelegate
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,14 @@ import QtQuick.Controls
|
||||||
import QtQuick.Controls.Basic
|
import QtQuick.Controls.Basic
|
||||||
import QtWebEngine 1.2
|
import QtWebEngine 1.2
|
||||||
import FluentUI
|
import FluentUI
|
||||||
|
import AicsKB.FileTransferManager
|
||||||
|
|
||||||
FluArea {
|
FluArea {
|
||||||
id: content_area
|
id: content_area
|
||||||
paddings: 0
|
paddings: 0
|
||||||
backgroundColor: "#f9f9f9"
|
backgroundColor: "#f9f9f9"
|
||||||
property string type: ""
|
property string type: ""
|
||||||
property int knowledgeFileId
|
property string knowledgeFileId
|
||||||
signal download(string knowledgeFileId)
|
signal download(string knowledgeFileId)
|
||||||
signal clickTags(string tagName)
|
signal clickTags(string tagName)
|
||||||
|
|
||||||
|
@ -134,6 +135,7 @@ FluArea {
|
||||||
}
|
}
|
||||||
onClicked: {
|
onClicked: {
|
||||||
emit: content_area.download(content_area.knowledgeFileId)
|
emit: content_area.download(content_area.knowledgeFileId)
|
||||||
|
FileTransferManager.download(content_area.knowledgeFileId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,7 +150,7 @@ FluArea {
|
||||||
id: video_view
|
id: video_view
|
||||||
FluMediaPlayer {
|
FluMediaPlayer {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: 270
|
implicitHeight: width * 9 / 16.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component {
|
Component {
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include "FileTransferListModel.h"
|
||||||
|
|
||||||
|
FileTransferListModel::FileTransferListModel(QObject *parent)
|
||||||
|
: QAbstractListModel(parent)
|
||||||
|
{
|
||||||
|
m_roleName.insert(kIdRole, "fileId");
|
||||||
|
m_roleName.insert(kNameRole, "name");
|
||||||
|
m_roleName.insert(kCompletedSizeRole, "completedSize");
|
||||||
|
m_roleName.insert(kTotalSizeRole, "totalSize");
|
||||||
|
|
||||||
|
m_data = {
|
||||||
|
{"v", "vivo", 1200, 2000},
|
||||||
|
{"m", "meizu", 1300, 1500},
|
||||||
|
{"a", "apple", 1400, 1400},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int FileTransferListModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
// For list models only the root node (an invalid parent) should return the list's size. For all
|
||||||
|
// other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
|
||||||
|
if (parent.isValid())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return m_data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant FileTransferListModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case kIdRole:
|
||||||
|
return m_data.value(index.row()).id;
|
||||||
|
case kNameRole:
|
||||||
|
return m_data.value(index.row()).name;
|
||||||
|
case kCompletedSizeRole:
|
||||||
|
return m_data.value(index.row()).completedSize;
|
||||||
|
case kTotalSizeRole:
|
||||||
|
return m_data.value(index.row()).totalSize;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> FileTransferListModel::roleNames() const
|
||||||
|
{
|
||||||
|
return m_roleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractItemModel *FileTransferListModel::model()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FileTransferListModel::insertItem(const FileItem &item)
|
||||||
|
{
|
||||||
|
beginInsertRows(QModelIndex(), 0, 0);
|
||||||
|
m_data.push_front(item);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileTransferListModel::setItem(const FileItem &item)
|
||||||
|
{
|
||||||
|
auto iter = std::find_if(m_data.begin(), m_data.end(), [&item](FileItem &i) {
|
||||||
|
return i.id == item.id;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (iter != m_data.end()) {
|
||||||
|
int row = iter - m_data.begin();
|
||||||
|
*iter = item;
|
||||||
|
emit dataChanged(createIndex(row, 0), createIndex(row, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef AICSKNOWLEDGEBASE_FILETRANSFERLISTMODEL_H
|
||||||
|
#define AICSKNOWLEDGEBASE_FILETRANSFERLISTMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
struct FileItem
|
||||||
|
{
|
||||||
|
QString id;
|
||||||
|
QString name;
|
||||||
|
int completedSize;
|
||||||
|
int totalSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FileTransferListModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FileTransferListModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
// Basic functionality:
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
void insertItem(const FileItem &item);
|
||||||
|
|
||||||
|
void setItem(const FileItem &item);
|
||||||
|
|
||||||
|
Q_INVOKABLE QAbstractItemModel *model();
|
||||||
|
|
||||||
|
enum FileItemRole
|
||||||
|
{
|
||||||
|
kIdRole = Qt::UserRole + 1,
|
||||||
|
kNameRole,
|
||||||
|
kCompletedSizeRole,
|
||||||
|
kTotalSizeRole
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
QList<FileItem> m_data;
|
||||||
|
QHash<int, QByteArray> m_roleName;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // AICSKNOWLEDGEBASE_FILETRANSFERLISTMODEL_H
|
|
@ -5,12 +5,59 @@
|
||||||
#include "FileTransferManager.h"
|
#include "FileTransferManager.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QtConcurrent/QtConcurrent>
|
||||||
|
|
||||||
FileTransferManager::FileTransferManager(QObject *parent) : QObject(parent)
|
static const std::string baseUrl = "http://127.0.0.1:4523/m1/2914957-0-default/";
|
||||||
|
|
||||||
|
static size_t writeDataCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
size_t realSize = size * nmemb;
|
||||||
|
static int current_index = 0;
|
||||||
|
int content_size = nmemb * size;
|
||||||
|
std::string result = std::string((char *) contents, content_size);
|
||||||
|
auto *pStr = (std::string *) userp;
|
||||||
|
if (pStr) {
|
||||||
|
(*pStr).append(result);
|
||||||
|
}
|
||||||
|
return realSize;
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode httpGet(const std::string &url, std::string &response, int timeout = 3000)
|
||||||
|
{
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
|
// 获取easy handle
|
||||||
|
CURL *easy_handle = curl_easy_init();
|
||||||
|
if (nullptr == easy_handle) {
|
||||||
|
curl_global_cleanup();
|
||||||
|
return CURLE_FAILED_INIT;
|
||||||
|
}
|
||||||
|
// 设置easy handle属性
|
||||||
|
//curl_easy_setopt(easy_handle, CURLOPT_HTTP_VERSION, (long) CURL_HTTP_VERSION_3ONLY);
|
||||||
|
curl_easy_setopt(easy_handle, CURLOPT_URL, (baseUrl + url).c_str());
|
||||||
|
curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, writeDataCallback);
|
||||||
|
curl_easy_setopt(easy_handle, CURLOPT_TIMEOUT, timeout);
|
||||||
|
curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, (void *) &response);
|
||||||
|
curl_easy_setopt(easy_handle, CURLOPT_FOLLOWLOCATION, 1L);
|
||||||
|
//curl_easy_setopt(easy_handle, CURLOPT_DEFAULT_PROTOCOL, "https");
|
||||||
|
// 执行数据请求
|
||||||
|
res = curl_easy_perform(easy_handle);
|
||||||
|
curl_easy_cleanup(easy_handle);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileTransferManager::FileTransferManager(FileTransferListModel &model, QObject *parent)
|
||||||
|
: model(model), QObject(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FileTransferManager::upload(QUrl fileUrl)
|
void FileTransferManager::upload(QUrl fileUrl)
|
||||||
{
|
{
|
||||||
qDebug() << fileUrl.fileName();
|
qDebug() << fileUrl.fileName();
|
||||||
|
@ -19,7 +66,7 @@ void FileTransferManager::upload(QUrl fileUrl)
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
curl = curl_easy_init();
|
curl = curl_easy_init();
|
||||||
if(curl) {
|
if (curl) {
|
||||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:4523/m1/2914957-0-default/");
|
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:4523/m1/2914957-0-default/");
|
||||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||||
|
@ -49,3 +96,42 @@ void FileTransferManager::upload(QUrl fileUrl)
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileTransferManager::download(QString fileId)
|
||||||
|
{
|
||||||
|
static int _fileId = 0;
|
||||||
|
fileId = QString::number(_fileId++);
|
||||||
|
|
||||||
|
QtConcurrent::run([fileId, this] {
|
||||||
|
qDebug() << "Start Get";
|
||||||
|
std::string resData;
|
||||||
|
if (CURLE_OK != httpGet(fileId.toStdString() + "/status", resData))
|
||||||
|
return;
|
||||||
|
|
||||||
|
qDebug() << resData.c_str();
|
||||||
|
auto resJson = QJsonDocument::fromJson(resData.c_str());
|
||||||
|
//if(!resJson["isCompleted"].toBool())
|
||||||
|
// return;
|
||||||
|
|
||||||
|
int size = resJson["size"].toInt();
|
||||||
|
FileItem item{fileId, resJson["md5"].toString(), 0, size};
|
||||||
|
QTimer::singleShot(0, qApp, [this, item]() {
|
||||||
|
model.insertItem(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
while (item.completedSize < item.totalSize) {
|
||||||
|
item.completedSize += 1;
|
||||||
|
QTimer::singleShot(0, qApp, [this, item]() {
|
||||||
|
model.setItem(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
std::this_thread::sleep_for(100ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
qDebug() << "End Get";
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,20 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include "FileTransferListModel.h"
|
||||||
|
|
||||||
class FileTransferManager: public QObject
|
class FileTransferManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit FileTransferManager(QObject *parent = nullptr);
|
explicit FileTransferManager(FileTransferListModel &model, QObject *parent = nullptr);
|
||||||
|
|
||||||
Q_INVOKABLE void upload(QUrl fileUrl);
|
Q_INVOKABLE void upload(QUrl fileUrl);
|
||||||
|
|
||||||
|
Q_INVOKABLE void download(QString fileId);
|
||||||
|
|
||||||
|
private:
|
||||||
|
FileTransferListModel &model;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,19 @@
|
||||||
#include <QtWebEngineQuick/qtwebenginequickglobal.h>
|
#include <QtWebEngineQuick/qtwebenginequickglobal.h>
|
||||||
#include <FramelessHelper/Quick/framelessquickmodule.h>
|
#include <FramelessHelper/Quick/framelessquickmodule.h>
|
||||||
#include <FramelessHelper/Core/private/framelessconfig_p.h>
|
#include <FramelessHelper/Core/private/framelessconfig_p.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
#include "HttpClient.h"
|
#include "HttpClient.h"
|
||||||
#include "FileTransferManager.h"
|
#include "FileTransferManager.h"
|
||||||
|
#include "FileTransferListModel.h"
|
||||||
|
|
||||||
FRAMELESSHELPER_USE_NAMESPACE
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
if (CURLE_OK != curl_global_init(CURL_GLOBAL_DEFAULT))
|
||||||
|
return CURLE_FAILED_INIT;
|
||||||
|
|
||||||
|
|
||||||
//将样式设置为Basic,不然会导致组件显示异常
|
//将样式设置为Basic,不然会导致组件显示异常
|
||||||
qputenv("QT_QUICK_CONTROLS_STYLE", "Basic");
|
qputenv("QT_QUICK_CONTROLS_STYLE", "Basic");
|
||||||
|
|
||||||
|
@ -38,8 +44,12 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
FramelessHelper::Quick::registerTypes(&engine);
|
FramelessHelper::Quick::registerTypes(&engine);
|
||||||
|
|
||||||
|
FileTransferListModel fileTransferListModel;
|
||||||
|
engine.rootContext()->setContextProperty("FileTransferListModel", &fileTransferListModel);
|
||||||
|
|
||||||
auto httpClient = new HttpClient(engine);
|
auto httpClient = new HttpClient(engine);
|
||||||
auto fileTransferManager = new FileTransferManager();
|
auto fileTransferManager = new FileTransferManager(fileTransferListModel);
|
||||||
|
|
||||||
qmlRegisterSingletonInstance<HttpClient>("AicsKB.HttpClient", 1, 0, "HttpClient", httpClient);
|
qmlRegisterSingletonInstance<HttpClient>("AicsKB.HttpClient", 1, 0, "HttpClient", httpClient);
|
||||||
qmlRegisterSingletonInstance<FileTransferManager>("AicsKB.FileTransferManager", 1, 0, "FileTransferManager",
|
qmlRegisterSingletonInstance<FileTransferManager>("AicsKB.FileTransferManager", 1, 0, "FileTransferManager",
|
||||||
|
@ -56,6 +66,6 @@ int main(int argc, char *argv[])
|
||||||
auto result = QGuiApplication::exec();
|
auto result = QGuiApplication::exec();
|
||||||
httpClient->deleteLater();
|
httpClient->deleteLater();
|
||||||
fileTransferManager->deleteLater();
|
fileTransferManager->deleteLater();
|
||||||
|
curl_global_cleanup();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue