Có chức năng Qt để chuyển các tệp vào Thùng rác thay vì thực sự xóa chúng, cho các hệ điều hành hỗ trợ nó hay tôi cần sử dụng mã dành riêng cho hệ điều hành?Chuyển các tập tin vào Thùng rác/Thùng rác trong Qt
Trả lời
Chưa có API nào.
https://bugreports.qt.io/browse/QTBUG-181
Vấn đề này được đóng lại và phiên bản sửa lỗi là: Một số phiên bản trong tương lai
Edit: Một vấn đề mới đã được mở tại https://bugreports.qt.io/browse/QTBUG-47703.
Tôi nghĩ rằng không có cách thức đa nền tảng. Các tệp di chuyển đơn giản đến vị trí "thùng rác" sẽ không có hiệu lực, bởi vì người dùng có thể tắt khả năng này.
Có lẽ, url này sẽ giúp: http://www.hardcoded.net/articles/send-files-to-trash-on-all-platforms.htm
Bài viết dành cho Python tuy nhiên, không phải cho C++. – sashoalm
@sashoalm Bài viết này nói về các API đã sử dụng. Nó không quan trọng từ những gì ngôn ngữ để gọi cho họ. –
Tôi khá chắc chắn rằng không có API Qt mà kết thúc tốt đẹp này cho tất cả các nền tảng được hỗ trợ. Điều đó có nghĩa là, thật không may, bạn sẽ phải viết mã nền tảng cụ thể.
Tôi không biết gì về cách phân phối Linux lưu trữ các tệp đã xóa và tôi cho rằng nó có thể thay đổi tùy thuộc vào trình quản lý tệp bạn đang sử dụng. Tôi tin rằng việc chuyển các tệp vào thư mục ~/.Trash
là cách làm tiêu chuẩn, nhưng tôi không chắc liệu tệp này có đáng tin cậy hay không. Ví dụ, trong trường hợp các tập tin được lưu trữ trên khối lượng bên ngoài.
Mọi thứ trở nên dễ dàng hơn một chút trên Mac OS X, nơi có API được hỗ trợ để thực hiện việc này: FSMoveObjectToTrashSync
, do Dịch vụ cốt lõi cung cấp. Ít nhất, đó là cách tôi nhớ bạn đang phải làm điều đó. The documentation tuyên bố rằng phương pháp này hiện không được chấp nhận trong OS X 10.8. Tôi không có ý tưởng thay thế được đề nghị là gì.
Là một lập trình viên Windows, tôi nghĩ rằng nền tảng đó dễ dàng hơn nhiều. :-) Các giải pháp cơ bản là để gọi SHFileOperation
chức năng:
#include <Windows.h> // general Windows header file
#include <ShellAPI.h> // for shell functions, like SHFileOperation
#include <string> // (or use QString)
void RecycleFileOnWindows()
{
std::wstring path = L"C:\\Users\\Administrator\\Documents\\deleteme.txt";
path.append(1, L'\0'); // path string must be double nul-terminated
SHFILEOPSTRUCT shfos = {};
shfos.hwnd = nullptr; // handle to window that will own generated windows, if applicable
shfos.wFunc = FO_DELETE;
shfos.pFrom = path.c_str();
shfos.pTo = nullptr; // not used for deletion operations
shfos.fFlags = FOF_ALLOWUNDO; // use the recycle bin
const int retVal = SHFileOperation(&shfos);
if (retVal != 0)
{
// The operation failed...
if (shfos.fAnyOperationsAborted)
{
// ...but that's because the user canceled.
MessageBox(nullptr, L"Operation was canceled", nullptr, MB_OK | MB_ICONINFORMATION);
}
else
{
// ...for one of the other reasons given in the documentation.
MessageBox(nullptr, L"Operation failed", nullptr, MB_OK | MB_ICONERROR);
}
}
}
Ngoài ra còn có cờ mà bạn có thể thiết lập để tùy chỉnh xác nhận, báo cáo lỗi, và hành vi khác. Tài liệu được liên kết chứa tất cả các chi tiết bạn cần để xây dựng dựa trên ví dụ cơ bản này.
Trên Windows Vista trở lên, chức năng SHFileOperation
đã được thay thế bằng các phương thức được cung cấp bởi giao diện IFileOperation
. Nếu bạn chỉ nhắm mục tiêu các phiên bản Windows sau này, bạn nên sử dụng giao diện này. Nếu không, SHFileOperation
sẽ tiếp tục hoạt động tốt.
Trên Linux có [đặc tả Thùng rác FreeDesktop.org] (http://www.ramendik.ru/docs/trashspec.html) dường như nói về trường hợp tệp được lưu trữ trên ổ đĩa ngoài. Nó được hỗ trợ bởi nhiều người quản lý tập tin Linux phổ biến bao gồm Nautilus và Dolphin. – silviubogan
Hoặc các nhân viên Qt có thể thực dụng và chỉ thực hiện nó cho Ubuntu và 1-2 bản phân phối phổ biến nhất tiếp theo. – sashoalm
Qt doesnt cung cấp MoveToTrash. Dưới đây là một phần của mã của tôi
cho Windows
#ifdef Q_OS_WIN32
#include "windows.h"
void MoveToTrashImpl(QString file){
QFileInfo fileinfo(file);
if(!fileinfo.exists())
throw OdtCore::Exception("File doesnt exists, cant move to trash");
WCHAR from[ MAX_PATH ];
memset(from, 0, sizeof(from));
int l = fileinfo.absoluteFilePath().toWCharArray(from);
Q_ASSERT(0 <= l && l < MAX_PATH);
from[ l ] = '\0';
SHFILEOPSTRUCT fileop;
memset(&fileop, 0, sizeof(fileop));
fileop.wFunc = FO_DELETE;
fileop.pFrom = from;
fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
int rv = SHFileOperation(&fileop);
if(0 != rv){
qDebug() << rv << QString::number(rv).toInt(0, 8);
throw OdtCore::Exception("move to trash failed");
}
}
#endif
và cho Linux
#ifdef Q_OS_LINUX
bool TrashInitialized = false;
QString TrashPath;
QString TrashPathInfo;
QString TrashPathFiles;
void MoveToTrashImpl(QString file){
#ifdef QT_GUI_LIB
if(!TrashInitialized){
QStringList paths;
const char* xdg_data_home = getenv("XDG_DATA_HOME");
if(xdg_data_home){
qDebug() << "XDG_DATA_HOME not yet tested";
QString xdgTrash(xdg_data_home);
paths.append(xdgTrash + "/Trash");
}
QString home = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
paths.append(home + "/.local/share/Trash");
paths.append(home + "/.trash");
foreach(QString path, paths){
if(TrashPath.isEmpty()){
QDir dir(path);
if(dir.exists()){
TrashPath = path;
}
}
}
if(TrashPath.isEmpty())
throw Exception("Cant detect trash folder");
TrashPathInfo = TrashPath + "/info";
TrashPathFiles = TrashPath + "/files";
if(!QDir(TrashPathInfo).exists() || !QDir(TrashPathFiles).exists())
throw Exception("Trash doesnt looks like FreeDesktop.org Trash specification");
TrashInitialized = true;
}
QFileInfo original(file);
if(!original.exists())
throw Exception("File doesnt exists, cant move to trash");
QString info;
info += "[Trash Info]\nPath=";
info += original.absoluteFilePath();
info += "\nDeletionDate=";
info += QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss.zzzZ");
info += "\n";
QString trashname = original.fileName();
QString infopath = TrashPathInfo + "/" + trashname + ".trashinfo";
QString filepath = TrashPathFiles + "/" + trashname;
int nr = 1;
while(QFileInfo(infopath).exists() || QFileInfo(filepath).exists()){
nr++;
trashname = original.baseName() + "." + QString::number(nr);
if(!original.completeSuffix().isEmpty()){
trashname += QString(".") + original.completeSuffix();
}
infopath = TrashPathInfo + "/" + trashname + ".trashinfo";
filepath = TrashPathFiles + "/" + trashname;
}
QDir dir;
if(!dir.rename(original.absoluteFilePath(), filepath)){
throw Exception("move to trash failed");
}
File infofile;
infofile.createUtf8(infopath, info);
#else
Q_UNUSED(file);
throw Exception("Trash in server-mode not supported");
#endif
}
#endif
if(QSysInfo::kernelType()=="linux")
{
QDateTime currentTime(QDateTime::currentDateTime()); // save System time
QString trashFilePath=QDir::homePath()+"/.local/share/Trash/files/"; // trash file path contain delete files
QString trashInfoPath=QDir::homePath()+"/.local/share/Trash/info/"; // trash info path contain delete files information
// create file format for trash info file----- START
QFile infoFile(trashInfoPath+FileName.completeBaseName()+"."+FileName.completeSuffix()+".trashinfo"); //filename+extension+.trashinfo // create file information file in /.local/share/Trash/info/ folder
infoFile.open(QIODevice::ReadWrite);
QTextStream stream(&infoFile); // for write data on open file
stream<<"[Trash Info]"<<endl;
stream<<"Path="+QString(QUrl::toPercentEncoding(FileName.absoluteFilePath(),"~_-./"))<<endl; // convert path string in percentage decoding scheme string
stream<<"DeletionDate="+currentTime.toString("yyyy-MM-dd")+"T"+currentTime.toString("hh:mm:ss")<<endl; // get date and time format YYYY-MM-DDThh:mm:ss
infoFile.close();
// create info file format of trash file----- END
QDir file;
file.rename(FileName.absoluteFilePath(),trashFilePath+FileName.completeBaseName()+"."+FileName.completeSuffix()); // rename(file old path, file trash path)
}
Chào mừng bạn đến với stackoverflow. Vui lòng giải thích điều gì đó về câu trả lời của bạn. –
Chỉ cần cẩn thận với 'QSysInfo :: kernelType() ==" linux "', hạt nhân của Android cũng là Linux. – sashoalm
file rác trong linux tồn tại /home/user_name/.local/share/Trash/files/
thư mục nhưng nó cũng đòi hỏi tập tin thông tin cho mỗi tập tin rác mà tồn tại trong thư mục /home/user_name/.local/share/Trash/info/
.khi chúng tôi muốn chuyển tệp vào thùng rác, hãy chuyển tệp vào thư mục /home/user_name/.local/share/Trash/files/
và tạo tệp thông tin trong thư mục /home/user_name/.local/share/Trash/info/
. bên trong .trashinfo định dạng sử dụng lược đồ giải mã phần trăm cho đường dẫn tệp đã đặt nơi tệp tồn tại, tệp thông tin cũng chứa thời gian và ngày xóa.
Xử lý vấn đề lạ. Đóng cửa là ...? Sẽ không sửa chữa? Quá khó? Thông thường, khi câu trả lời là "có thể sau này", vấn đề là chỉ còn lại mở. –
Lý do: Nằm ngoài phạm vi – fjardon
Có sự cố mới mở lại lỗi cũ này tại đây: https://bugreports.qt.io/browse/QTBUG-47703 – Felix