1.功能實現
支援圖片、或者資料夾拖拽上傳,會自動獲取資料夾中的圖片。對拖入的檔案做格式判斷,不符合格式要求的會不支援拖入,拖入後展示在list列表中,可以進行刪除,和上下滾動檢視;
#ifndef DRAGDROPPIC_H #define DRAGDROPPIC_H #include <QWidget> #include "ui_DragDropPic.h" #include<QDragEnterEvent> #include <QDropEvent> #include <QMimeData> #include<QLabel> #include "DirPicItem.h" #include "SearchPicThread.h" #include "HelpButton.h" #include "AddPicHelp.h" class DragDropPic : public QWidget { Q_OBJECT public: DragDropPic(QWidget *parent = 0); ~DragDropPic(); void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); void dragLeaveEvent(QDragLeaveEvent *event); void AddSelectedFile(QStringList listPath); void wheelEvent(QWheelEvent *e); void ClearContont(); void CheckIsSystemPath(QStringList& listDir); void resizeEvent(QResizeEvent *event); bool IsReady() { return m_pSearchPicThread->isRunning() ? false : true; }; QStringList GetNoRepeatPicPath(); int GetNoRepeatPicNum(); void CheckLeftPicNum(bool bAlarm=false); public slots: void UpdateFileList(); void SlotSelectPicFile(); void SlotSearchPicFinished(QVariantMap picData); void SetLeftPicNum(int left) { m_leftPicNum = left; }; void SlotShowHelpWidget(bool show); signals: void SignalError(int type, QString strContent); void SignalUpdateLeftPicNum(int num); private: Ui::DragDropPic ui; QStringList m_strListFilePath; QMap<QString, QVariant>m_mapFilePathPic; SearchPicThread* m_pSearchPicThread; int m_leftPicNum = 0;//剩餘 HelpButton* m_pHelpButton; AddPicHelp m_AddPicHelp; }; #endif // DRAGDROPPIC_H
cpp檔案
#include "DragDropPic.h" #include <QFileInfo> #include <QScrollBar> #include "MultiFileDirDialog.h" #include "ConfigInfo.h" #pragma execution_character_set("utf-8") DragDropPic::DragDropPic(QWidget *parent) : QWidget(parent) { ui.setupUi(this); ui.widgetRelease->hide(); ui.widgetPic->hide(); ui.listWidgetPic->verticalScrollBar()->setDisabled(true); connect(ui.vScrollBar, &QScrollBar::valueChanged, this, &DragDropPic::UpdateFileList); connect(ui.pBLibAddPic, &QPushButton::clicked, this, &DragDropPic::SlotSelectPicFile); m_pSearchPicThread = new SearchPicThread(this); connect(m_pSearchPicThread, &SearchPicThread::signalSearchPicResult, this, &DragDropPic::SlotSearchPicFinished); m_pHelpButton = new HelpButton(ui.widgetHelp); ui.horizontalLayoutHelp->addWidget(m_pHelpButton); connect(m_pHelpButton, &HelpButton::signalInHelpButton, this, &DragDropPic::SlotShowHelpWidget); } DragDropPic::~DragDropPic() { } /*對拖入的圖片做格式判斷*/ void DragDropPic::dragEnterEvent(QDragEnterEvent *event) { QStringList allowedExtensions; allowedExtensions << "jpg" << "jpeg" << "png" << "tiff"<<"JPG"<<"JPEG"<<"PNG"<<"TIFF"; const QMimeData *mimeData = event->mimeData(); int CountUnsurport = 0; QStringList listPath; if (mimeData->hasUrls()) { QList<QUrl> urls = mimeData->urls(); for (int i = 0; i < urls.size(); i++) { QString filePath = urls.at(i).toLocalFile(); // 通常只處理第一個url QFileInfo fileinfo(filePath); if (fileinfo.isDir()) { listPath.push_back(filePath); } else { QString extension = fileinfo.suffix(); if (allowedExtensions.contains(extension)) { listPath.push_back(filePath); } else { CountUnsurport++; } } } } if (CountUnsurport>0) { event->ignore(); // 接受拖動 } else { event->acceptProposedAction(); // 接受拖動 ui.widget->hide(); ui.widgetRelease->show(); ui.widgetAddPic->setStyleSheet(QLatin1String("\n" "QWidget#widgetAddPic\n" "{\n" " border: 1px dashed rgba(255, 255, 255, 0.3);\n" " border-radius: 4px;\n" " background:rgba(32, 128, 247, 0.16);\n" "}")); } } void DragDropPic::dropEvent(QDropEvent *event) { // 允許的副檔名列表 ui.widget->show(); ui.widgetPic->show(); ui.widgetRelease->hide(); ui.widgetAddPic->setStyleSheet(QLatin1String("\n" "QWidget#widgetAddPic\n" "{\n" " border: 1px dashed rgba(255, 255, 255, 0.3);\n" " border-radius: 4px;\n" " background: rgb(40, 40, 41);\n" "}")); QStringList allowedExtensions; allowedExtensions << "jpg" << "jpeg" << "png" << "tiff" << "JPG" << "JPEG" << "PNG" << "TIFF"; const QMimeData *mimeData = event->mimeData(); int CountUnsurport = 0; QStringList listPath; if (mimeData->hasUrls()) { QList<QUrl> urls = mimeData->urls(); for (int i = 0; i < urls.size(); i++) { QString filePath = urls.at(i).toLocalFile(); // 通常只處理第一個url QFileInfo fileinfo(filePath); if (fileinfo.isDir()) { listPath.push_back(filePath); } else { QString extension = fileinfo.suffix(); if (allowedExtensions.contains(extension)) { listPath.push_back(filePath); } else { CountUnsurport++; } } } } if (CountUnsurport>0) { emit SignalError(-3, QString("有%1個檔案不符合格式要求").arg(CountUnsurport)); return; } AddSelectedFile(listPath); } void DragDropPic::dragLeaveEvent(QDragLeaveEvent *event) { ui.widget->show(); ui.widgetRelease->hide(); ui.widgetAddPic->setStyleSheet(QLatin1String("\n" "QWidget#widgetAddPic\n" "{\n" " border: 1px dashed rgba(255, 255, 255, 0.3);\n" " border-radius: 4px;\n" " background: rgb(40, 40, 41);\n" "}")); } void DragDropPic::AddSelectedFile(QStringList listPath) { QStringList listDir; for (int i=0;i<listPath.size();i++) { //去除重複 if (m_mapFilePathPic.find(listPath[i])== m_mapFilePathPic.end()) { m_strListFilePath.push_back(listPath[i]); QFileInfo info(listPath[i]); if (info.isDir()) { listDir.append(listPath[i]); QStringList listpic; m_mapFilePathPic.insert(listPath[i] , listpic); } else { m_mapFilePathPic.insert(listPath[i], ""); } } } if (listDir.size()>0) { m_pSearchPicThread->StartSearchPic(listDir);//用執行緒搜尋資料夾中的圖片 } UpdateFileList(); CheckLeftPicNum(true); } //滾輪滾動時,列表也跟著滾動 void DragDropPic::wheelEvent(QWheelEvent *e) { int max = ui.vScrollBar->maximum(); int current = ui.vScrollBar->value(); if (ui.listWidgetPic->underMouse()) { if (e->delta()<0) { current++; if (current>max) { current = max; } } else { current--; if (current<0) { current = 0; } } ui.vScrollBar->setValue(current); } } void DragDropPic::ClearContont() { ui.listWidgetPic->clear(); m_mapFilePathPic.clear(); m_strListFilePath.clear(); ui.vScrollBar->setValue(0); ui.widgetPic->hide(); } void DragDropPic::UpdateFileList() { int total = m_strListFilePath.size(); if (total > 0) { ui.widgetPic->show(); } else { ui.widgetPic->hide(); } int pagesize = ui.listWidgetPic->height() / 28; if (total>pagesize) { ui.vScrollBar->setMaximum(total-pagesize); ui.vScrollBar->show(); } else { ui.vScrollBar->setMaximum(0); ui.vScrollBar->hide(); } int current = ui.vScrollBar->value(); int listsize = ui.listWidgetPic->count(); DirPicItem* pDirPicItem = NULL; QListWidgetItem* pItem=NULL; if (total <= pagesize)//總數不足一頁 { if (listsize>=total)//列表中已有大於總數 { //回收多餘的item for (int s = total; s < listsize; s++) { pItem = (QListWidgetItem*)ui.listWidgetPic->takeItem(0);//會刪除掉set上去的item if (pItem) { pDirPicItem = (DirPicItem*)ui.listWidgetPic->itemWidget(pItem); if (pDirPicItem) { delete pDirPicItem; pDirPicItem = NULL; } delete pItem; pItem = NULL; } } } else//已有少於總數插入不足 { for (int s = listsize; s < total; s++) { pItem = new QListWidgetItem(ui.listWidgetPic); pDirPicItem = new DirPicItem(ui.listWidgetPic); connect(pDirPicItem->ui.pBClose, &QPushButton::clicked, this, [=] { QString strFilePath = pDirPicItem->GetDirFile(); m_mapFilePathPic.remove(strFilePath); for (int i = 0; i < m_strListFilePath.size(); i++) { if (m_strListFilePath[i] == strFilePath) { m_strListFilePath.removeAt(i); break; } } UpdateFileList(); CheckLeftPicNum(); }); ui.listWidgetPic->addItem(pItem); ui.listWidgetPic->setItemWidget(pItem,pDirPicItem); } } } else//總數大於一頁 { if (listsize< pagesize) { for (int s = listsize; s < pagesize; s++) { pItem = new QListWidgetItem(ui.listWidgetPic); pDirPicItem = new DirPicItem(ui.listWidgetPic); connect(pDirPicItem->ui.pBClose, &QPushButton::clicked, this, [=] { QString strFilePath = pDirPicItem->GetDirFile(); m_mapFilePathPic.remove(strFilePath); for (int i=0;i<m_strListFilePath.size();i++) { if (m_strListFilePath[i]==strFilePath) { m_strListFilePath.removeAt(i); break; } } UpdateFileList(); CheckLeftPicNum(); }); ui.listWidgetPic->addItem(pItem); ui.listWidgetPic->setItemWidget(pItem, pDirPicItem); } } } listsize = ui.listWidgetPic->count(); for (int i= current,count=0;i<total&& count<listsize;i++, count++) { pItem = (QListWidgetItem*)(ui.listWidgetPic->item(count)); if (pItem) { pDirPicItem = (DirPicItem*)ui.listWidgetPic->itemWidget(pItem);//會刪除掉set上去的item if (pDirPicItem) { pDirPicItem->SetDirFile(m_strListFilePath[i]); QFileInfo info(m_strListFilePath[i]); if (info.isDir()) { if (m_mapFilePathPic.find(m_strListFilePath[i])!=m_mapFilePathPic.end()) { QStringList listpic = m_mapFilePathPic[m_strListFilePath[i]].toStringList(); if (listpic.size()>0) { pDirPicItem->SetDirPicNum(listpic.size()); } } } } } } } void DragDropPic::SlotSelectPicFile() { MultiFileDirDialog fileDialog(NULL); fileDialog.setWindowTitle("選擇資料夾或圖片"); fileDialog.setOption(QFileDialog::ShowDirsOnly, false); fileDialog.setNameFilter("vedio(*.jpg *.jpeg *.png *.tiff *.JPG *.JPEG *.PNG *.TIFF)"); if (fileDialog.exec() == QDialog::Accepted) { QStringList selectFiles = fileDialog.selectedFiles(); if (selectFiles.size() > 0) { CheckIsSystemPath(selectFiles); //CheckIsNameTooLong(selectFiles); if (selectFiles.size() > 0) { AddSelectedFile(selectFiles); } } } } void DragDropPic::SlotSearchPicFinished(QVariantMap picData) { for (auto it = picData.begin(); it!= picData.end(); it++) { if (m_mapFilePathPic.find(it.key())!=m_mapFilePathPic.end()) { m_mapFilePathPic.insert(it.key(), it.value()); } } UpdateFileList(); CheckLeftPicNum(true); } void DragDropPic::SlotShowHelpWidget(bool show) { if (show) { m_AddPicHelp.show(); QPoint ppint =QCursor::pos(); m_AddPicHelp.move(ppint.x() - 30, ppint.y() + 20); } else { m_AddPicHelp.hide(); } } void DragDropPic::resizeEvent(QResizeEvent *event) { UpdateFileList(); } QStringList DragDropPic::GetNoRepeatPicPath() { QStringList listpic; QMap<QString, QString> mapPic; for (auto it=m_mapFilePathPic.begin();it!=m_mapFilePathPic.end();it++) { QFileInfo info(it.key()); if (info.isDir()) { QStringList Items = it.value().toStringList(); for (int i = 0; i < Items.size(); i++) { mapPic.insert(Items[i], Items[i]); } } else { mapPic.insert(it.key(), it.key()); } } listpic = mapPic.keys(); return listpic; } //獲取不重複圖片數量 int DragDropPic::GetNoRepeatPicNum() { QMap<QString, QString> mapPic; for (auto it = m_mapFilePathPic.begin(); it != m_mapFilePathPic.end(); it++) { QFileInfo info(it.key()); if (info.isDir()) { QStringList Items = it.value().toStringList(); for (int i = 0; i < Items.size(); i++) { mapPic.insert(Items[i], Items[i]); } } else { mapPic.insert(it.key(), it.key()); } } return mapPic.size(); } //判斷圖片數量是否超出上限 void DragDropPic::CheckLeftPicNum(bool bAlarm) { int selectNum = GetNoRepeatPicNum(); emit SignalUpdateLeftPicNum(m_leftPicNum - selectNum); if (m_leftPicNum== selectNum) { if (bAlarm) { emit SignalError(-3, QString("選擇的圖片數量已滿上限%1").arg(CConfig::instance()->GetLibPeopleLimit())); } } else if (m_leftPicNum<selectNum) { if (bAlarm) { emit SignalError(-3, QString("選擇的圖片數量超過上限%1,超出%2張").arg(CConfig::instance()->GetLibPeopleLimit()).arg(selectNum-m_leftPicNum)); } } } //判斷是否系統盤 void DragDropPic::CheckIsSystemPath(QStringList& listDir) { QStringList filelist; int count = 0; QString strError = ""; #ifdef WIN32 for (int i = 0; i < listDir.size(); i++) { if (listDir[i].length() <= 3) { count++; } else { filelist.append(listDir[i]); } } strError = "不能選擇系統盤,請建立一個資料夾"; #else for (int i = 0; i < listDir.size(); i++) { if (listDir[i].length() <= 1) { count++; } else { filelist.append(listDir[i]); } } strError = "不能選擇根目錄,請建立一個資料夾"; #endif if (count > 0) { emit SignalError(-1, strError); } listDir = filelist; }
遍歷查詢資料夾中圖片的執行緒
標頭檔案
#ifndef SEARCHPICTHREAD_H #define SEARCHPICTHREAD_H #include <QThread> #include<QMap> #include <QVariant> #include<QVariantMap> class SearchPicThread : public QThread { Q_OBJECT public: SearchPicThread(QObject *parent); ~SearchPicThread(); void StartSearchPic(QStringList list); void run(); void stopSearch() { m_stoped = true; }; void RecursiveInputDirFiles(QString strDir, QStringList& listPic); signals: void signalSearchPicResult(QVariantMap picData); private: QStringList m_listDir; bool m_stoped = false; }; #endif // SEARCHPICTHREAD_H
cpp檔案
#include "SearchPicThread.h" #include <QDir> SearchPicThread::SearchPicThread(QObject *parent) : QThread(parent) { } SearchPicThread::~SearchPicThread() { } void SearchPicThread::StartSearchPic(QStringList list) { m_listDir.append(list); if (this->isRunning()==false) { m_stoped = false; start(); } } void SearchPicThread::run() { QVariantMap mappic; while (m_listDir.size()>0) { if (m_stoped == true)//退出 { break; } QString strDir = m_listDir.front(); m_listDir.pop_front(); QStringList listPic; RecursiveInputDirFiles(strDir, listPic); mappic.insert(strDir, listPic); } emit signalSearchPicResult(mappic); } void SearchPicThread::RecursiveInputDirFiles(QString strDir, QStringList& listPic) { QDir dirFile(strDir); QDir dirDir(strDir); if (!dirDir.exists()) { return; } dirFile.setSorting(QDir::Time);//優先顯示目錄 dirDir.setSorting(QDir::Time); //列出dir(path)目錄檔案下所有檔案和目錄資訊,儲存到file_list容器 QStringList fileNameFilter; //影片格式 fileNameFilter << "*.jpg" << "*.jpeg" << "*.png" << "*.tiff"; dirFile.setNameFilters(fileNameFilter); QFileInfoList file_list = dirFile.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoSymLinks); //列出dir(path)目錄下所有子資料夾 QFileInfoList folder_list = dirDir.entryInfoList(QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot); if (file_list.size() == 0 && folder_list.size() == 0) { return; } //新增影片檔案到列表 QString strfilepath = ""; for (int i = 0; i < file_list.size(); i++) { strfilepath = file_list[i].absoluteFilePath(); listPic.append(strfilepath); } //進行子資料夾folder_list遞迴遍歷,將內容存入file_list容器 for (int i = 0; i != folder_list.size(); i++) { RecursiveInputDirFiles(folder_list.at(i).absoluteFilePath(), listPic); } }