Compare commits
No commits in common. "3f30e4ed4d740cf59c688277e5fff41a5ce7ab93" and "9ea3b2c30bfa47c1fd494ecba4db9dc43f8f0eba" have entirely different histories.
3f30e4ed4d
...
9ea3b2c30b
|
@ -26,6 +26,22 @@ 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
|
||||||
|
|
||||||
|
@ -85,7 +101,10 @@ FluWindow {
|
||||||
onReady: {
|
onReady: {
|
||||||
setTitleBarItem(title_bar)
|
setTitleBarItem(title_bar)
|
||||||
moveWindowToDesktopCenter()
|
moveWindowToDesktopCenter()
|
||||||
title_bar.setHitTestVisibleItems(framless_helper)
|
setHitTestVisible(title_bar.minimizeButton())
|
||||||
|
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,15 +110,6 @@ 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
|
||||||
|
@ -213,10 +204,7 @@ Rectangle {
|
||||||
return btn_close
|
return btn_close
|
||||||
}
|
}
|
||||||
|
|
||||||
function setHitTestVisibleItems(frameless_helper) {
|
function transferButton() {
|
||||||
frameless_helper.setHitTestVisible(btn_minimize)
|
return btn_transfer
|
||||||
frameless_helper.setHitTestVisible(btn_maximize)
|
|
||||||
frameless_helper.setHitTestVisible(btn_close)
|
|
||||||
frameless_helper.setHitTestVisible(btn_transfer)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,29 +16,52 @@ Popup {
|
||||||
FluShadow {}
|
FluShadow {}
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: FluScrollablePage {
|
contentItem: Item {
|
||||||
anchors.fill: parent
|
anchors.top: parent.top
|
||||||
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: completedSize / totalSize
|
progress: progressValue
|
||||||
indeterminate: false
|
indeterminate: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ListView //视图-设置委托和模型,根据委托提供的展示方式展示模型提供的数据
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
model: itemModel
|
||||||
|
delegate: itemDelegate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,13 @@ 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 string knowledgeFileId
|
property int knowledgeFileId
|
||||||
signal download(string knowledgeFileId)
|
signal download(string knowledgeFileId)
|
||||||
signal clickTags(string tagName)
|
signal clickTags(string tagName)
|
||||||
|
|
||||||
|
@ -135,7 +134,6 @@ FluArea {
|
||||||
}
|
}
|
||||||
onClicked: {
|
onClicked: {
|
||||||
emit: content_area.download(content_area.knowledgeFileId)
|
emit: content_area.download(content_area.knowledgeFileId)
|
||||||
FileTransferManager.download(content_area.knowledgeFileId)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,7 +148,7 @@ FluArea {
|
||||||
id: video_view
|
id: video_view
|
||||||
FluMediaPlayer {
|
FluMediaPlayer {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: width * 9 / 16.
|
implicitHeight: 270
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component {
|
Component {
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
#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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
#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,59 +5,12 @@
|
||||||
#include "FileTransferManager.h"
|
#include "FileTransferManager.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QtConcurrent/QtConcurrent>
|
|
||||||
|
|
||||||
static const std::string baseUrl = "http://127.0.0.1:4523/m1/2914957-0-default/";
|
FileTransferManager::FileTransferManager(QObject *parent) : QObject(parent)
|
||||||
|
|
||||||
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();
|
||||||
|
@ -66,7 +19,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);
|
||||||
|
@ -96,42 +49,3 @@ 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,20 +8,14 @@
|
||||||
|
|
||||||
#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(FileTransferListModel &model, QObject *parent = nullptr);
|
explicit FileTransferManager(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,19 +7,13 @@
|
||||||
#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");
|
||||||
|
|
||||||
|
@ -44,12 +38,8 @@ 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(fileTransferListModel);
|
auto fileTransferManager = new FileTransferManager();
|
||||||
|
|
||||||
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",
|
||||||
|
@ -66,6 +56,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