Est-il possible d'ouvrir un dossier dans Windows Explorer/OS X Finder, puis de sélectionner/mettre en surbrillance un fichier de ce dossier et de le faire de manière multiplateforme? En ce moment, je fais quelque chose comme
QDesktopServices::openUrl( QUrl::fromLocalFile( path ) );
où path
est un chemin complet du dossier que je veux ouvrir. Évidemment, cela ne fera qu'ouvrir le dossier et je devrai rechercher manuellement le fichier dont j'ai besoin. C'est un peu un problème quand il y a des milliers de fichiers dans ce dossier.
Si je fais un chemin vers un fichier spécifique dans ce dossier, alors ce fichier est ouvert avec l'application par défaut pour ce type MIME, et ce n'est pas ce dont j'ai besoin. Au lieu de cela, j'ai besoin de la fonctionnalité équivalente à "Révéler dans le Finder" ou "Afficher dans l'explorateur".
Qt Creator ( /source ) a cette fonctionnalité, il est facile de la copier:
void FileUtils::showInGraphicalShell(QWidget *parent, const QString &pathIn)
{
const QFileInfo fileInfo(pathIn);
// Mac, Windows support folder or file.
if (HostOsInfo::isWindowsHost()) {
const FileName Explorer = Environment::systemEnvironment().searchInPath(QLatin1String("Explorer.exe"));
if (Explorer.isEmpty()) {
QMessageBox::warning(parent,
QApplication::translate("Core::Internal",
"Launching Windows Explorer Failed"),
QApplication::translate("Core::Internal",
"Could not find Explorer.exe in path to launch Windows Explorer."));
return;
}
QStringList param;
if (!fileInfo.isDir())
param += QLatin1String("/select,");
param += QDir::toNativeSeparators(fileInfo.canonicalFilePath());
QProcess::startDetached(Explorer.toString(), param);
} else if (HostOsInfo::isMacHost()) {
QStringList scriptArgs;
scriptArgs << QLatin1String("-e")
<< QString::fromLatin1("tell application \"Finder\" to reveal POSIX file \"%1\"")
.arg(fileInfo.canonicalFilePath());
QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
scriptArgs.clear();
scriptArgs << QLatin1String("-e")
<< QLatin1String("tell application \"Finder\" to activate");
QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
} else {
// we cannot select a file here, because no file browser really supports it...
const QString folder = fileInfo.isDir() ? fileInfo.absoluteFilePath() : fileInfo.filePath();
const QString app = UnixUtils::fileBrowser(ICore::settings());
QProcess browserProc;
const QString browserArgs = UnixUtils::substituteFileBrowserParameters(app, folder);
bool success = browserProc.startDetached(browserArgs);
const QString error = QString::fromLocal8Bit(browserProc.readAllStandardError());
success = success && error.isEmpty();
if (!success)
showGraphicalShellError(parent, app, error);
}
}
Un autre article de blog connexe (avec un code plus simple, je ne l’ai pas essayé et je ne peux donc pas commenter), est this .
Modifier:
Il y a un bogue dans le code d'origine lorsque pathIn contient des espaces sous Windows. QProcess :: startDetached citera automatiquement un paramètre s'il contient des espaces. Toutefois, l'Explorateur Windows ne reconnaîtra pas un paramètre entouré de guillemets et ouvrira l'emplacement par défaut. Essayez vous-même dans la ligne de commande Windows:
echo. > "C:\a file with space.txt"
:: The following works
C:\Windows\Explorer.exe /select,C:\a file with space.txt
:: The following does not work
C:\Windows\Explorer.exe "/select,C:\a file with space.txt"
Ainsi,
QProcess::startDetached(Explorer, QStringList(param));
est changé en
QString command = Explorer + " " + param;
QProcess::startDetached(command);
Vous pouvez probablement utiliser QFileDialog::getOpenFileName
pour obtenir le nom du fichier. La documentation est disponible ici .. La fonction ci-dessus va renvoyer le chemin complet, y compris le nom du fichier et son extensionle cas échéant ..
Ensuite, vous pouvez donner
QDesktopServices::openUrl(path);
pour ouvrir le fichier dans son application par défaut, où path
sera la QString
renvoyée par QFileDialog::getOpenFileName
.
J'espère que ça aide..
Ouvrir le fichier dans Windows Explorer (pas le navigateur)
void OpenFileInExplorer()
{
QString path = "C:/exampleDir/example.txt";
QStringList args;
args << "/select," << QDir::toNativeSeparators(path);
QProcess *process = new QProcess(this);
process->start("Explorer.exe", args);
}
Voici le code que je suis allé avec basé sur les entrées d'une réponse précédente. Cette version ne dépend pas d'autres méthodes de Qt Creator, accepte un fichier ou un répertoire et dispose d'un mode de secours pour la gestion des erreurs et d'autres plates-formes:
void Util::showInFolder(const QString& path)
{
QFileInfo info(path);
#if defined(Q_OS_WIN)
QStringList args;
if (!info.isDir())
args << "/select,";
args << QDir::toNativeSeparators(path);
if (QProcess::startDetached("Explorer", args))
return;
#Elif defined(Q_OS_MAC)
QStringList args;
args << "-e";
args << "tell application \"Finder\"";
args << "-e";
args << "activate";
args << "-e";
args << "select POSIX file \"" + path + "\"";
args << "-e";
args << "end tell";
args << "-e";
args << "return";
if (!QProcess::execute("/usr/bin/osascript", args))
return;
#endif
QDesktopServices::openUrl(QUrl::fromLocalFile(info.isDir()? path : info.path()));
}
Cette solution fonctionne à la fois sous Windows et Mac:
void showFileInFolder(const QString &path){
#ifdef _WIN32 //Code for Windows
QProcess::startDetached("Explorer.exe", {"/select,", QDir::toNativeSeparators(path)});
#Elif defined(__Apple__) //Code for Mac
QProcess::execute("/usr/bin/osascript", {"-e", "tell application \"Finder\" to reveal POSIX file \"" + path + "\""});
QProcess::execute("/usr/bin/osascript", {"-e", "tell application \"Finder\" to activate"});
#endif
}