如何使用 Qt“在 Finder 中显示”或“在资源管理器中显示”

问题描述 投票:0回答:6

是否可以在 Windows 资源管理器/OS X Finder 中打开一个文件夹,然后选择/突出显示该文件夹中的一个文件,并以跨平台方式执行此操作?现在,我做了类似的事情

QDesktopServices::openUrl( QUrl::fromLocalFile( path ) );

其中

path
是我要打开的文件夹的完整路径。显然,这只会打开该文件夹,我必须手动查找我需要的文件。当该文件夹中有数千个文件时,这有点问题。

如果我将其设置为该文件夹中特定文件的路径,则该文件将使用该 mime 类型的默认应用程序打开,而这不是我所需要的。相反,我需要相当于“在 Finder 中显示”或“在资源管理器中显示”的功能。

c++ qt qt4
6个回答
50
投票

Qt Creatorsource)有这个功能,复制它很简单:

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);
    }
}

另一篇相关博客文章(代码更简单,我没有尝试过,所以无法发表评论),是this

编辑:

在 Windows 上,当 pathIn 包含空格时,原始代码存在错误。如果参数包含空格,QProcess::startDetached将自动引用参数。但是,Windows 资源管理器无法识别用引号引起来的参数,而是会打开默认位置。在 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"

因此,

QProcess::startDetached(explorer, QStringList(param));

更改为

QString command = explorer + " " + param;
QProcess::startDetached(command);

11
投票

也许您可以使用

QFileDialog::getOpenFileName
来获取文件名。文档可在此处..上述函数将返回完整路径,包括文件名及其扩展名如果有..

然后你可以给

QDesktopServices::openUrl(path);

在默认应用程序中打开文件,其中

path
将是
QString
返回的
QFileDialog::getOpenFileName

希望有帮助..


6
投票

这是我根据之前答案的输入使用的代码。该版本不依赖于 Qt Creator 中的其他方法,接受文件或目录,并且具有错误处理和其他平台的回退模式:

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()));
}

5
投票

在 Windows 资源管理器(而不是浏览器)中打开文件

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); 

}

2
投票

此解决方案适用于 Windows 和 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
}

0
投票

这是一个类似于 Dan Dennedy 的答案 的 Linux 选项,它利用 DBus:

#elif defined(Q_OS_LINUX)
    QStringList args;
    args << "--session";
    args << "--dest=org.freedesktop.FileManager1";
    args << "--type=method_call";
    args << "/org/freedesktop/FileManager1";
    args << "org.freedesktop.FileManager1.ShowItems";
    args << "array:string:file://" + path;
    args << "string:";
    if (QProcess::startDetached("dbus-send", args))
        return;
© www.soinside.com 2019 - 2024. All rights reserved.