2010-08-16 1 views
35

Можно ли открыть папку в Finder Windows/Finder OS X, а затем выбрать/выделить один файл в этой папке и сделать это в кросс-платформе путь? Прямо сейчас, я сделать что-то вродеКак «показать в Finder» или «Показать в проводнике» с Qt

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

где path полный путь к папке Я хочу открыть. Очевидно, это просто откроет папку, и мне придется отследить файл, который мне нужен вручную. Это немного проблема, когда в этой папке есть тысячи файлов.

Если я создаю путь к определенному файлу в этой папке, тогда этот файл открыт с приложением по умолчанию для этого типа mime, и это не то, что мне нужно. Вместо этого мне нужна функциональность, эквивалентная «Reveal in Finder» или «Show in Explorer».

+0

Для уточнения: Вы имеете в виду как при нажатии на «Reveal в Finder "или" Show in Explorer "? –

+0

@Austin Да, я имел в виду именно что-то вроде «Reveal in Finder» или «Show in Explorer» – nnc

ответ

5

Возможно, вы можете использовать QFileDialog::getOpenFileName, чтобы получить имя файла. Документация доступна here .. выше функция возвращает полный путь, включая имя файла и его расширениеесли любой ..

Тогда вы можете дать

QDesktopServices::openUrl(path);

, чтобы открыть файл в своей заявке по умолчанию, где path будет QString, возвращенный QFileDialog::getOpenFileName.

Надеется, что это помогает ..

+3

спасибо за ответ, но это не то, что мне нужно. Я уточнил вопрос, чтобы попытаться это разъяснить. Мне нужна функция «Показать в Finder» или «Показать в проводнике». – nnc

+0

OpenUrl() - метод QDesktopServices фактически показывает файл/каталог в проводнике. Вы добавили «файл: ///» в строку пути? – Stradivari

+1

@liaK: OP просто хочет, чтобы файл ** показывал ** в проводнике, а не ** открывал ** его. Ваш метод попытается ** открыть ** сам файл. – diverger

33

Qt Creator имеет такую ​​функциональность, это тривиально, чтобы скопировать его:

void FolderNavigationWidget::showInGraphicalShell(QWidget *parent, const QString &pathIn) 
{ 
    // Mac, Windows support folder or file. 
#if defined(Q_OS_WIN) 
    const QString explorer = Environment::systemEnvironment().searchInPath(QLatin1String("explorer.exe")); 
    if (explorer.isEmpty()) { 
     QMessageBox::warning(parent, 
          tr("Launching Windows Explorer failed"), 
          tr("Could not find explorer.exe in path to launch Windows Explorer.")); 
     return; 
    } 
    QString param; 
    if (!QFileInfo(pathIn).isDir()) 
     param = QLatin1String("/select,"); 
    param += QDir::toNativeSeparators(pathIn); 
    QString command = explorer + " " + param; 
    QProcess::startDetached(command); 
#elif defined(Q_OS_MAC) 
    Q_UNUSED(parent) 
    QStringList scriptArgs; 
    scriptArgs << QLatin1String("-e") 
       << QString::fromLatin1("tell application \"Finder\" to reveal POSIX file \"%1\"") 
            .arg(pathIn); 
    QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs); 
    scriptArgs.clear(); 
    scriptArgs << QLatin1String("-e") 
       << QLatin1String("tell application \"Finder\" to activate"); 
    QProcess::execute("/usr/bin/osascript", scriptArgs); 
#else 
    // we cannot select a file here, because no file browser really supports it... 
    const QFileInfo fileInfo(pathIn); 
    const QString folder = fileInfo.absoluteFilePath(); 
    const QString app = Utils::UnixUtils::fileBrowser(Core::ICore::instance()->settings()); 
    QProcess browserProc; 
    const QString browserArgs = Utils::UnixUtils::substituteFileBrowserParameters(app, folder); 
    if (debug) 
     qDebug() << browserArgs; 
    bool success = browserProc.startDetached(browserArgs); 
    const QString error = QString::fromLocal8Bit(browserProc.readAllStandardError()); 
    success = success && error.isEmpty(); 
    if (!success) 
     showGraphicalShellError(parent, app, error); 
#endif 
} 

Другие, связанное сообщение в блоге (с простым кодом, я не пробовал, так что я могу 't comment), это this.

Edit:

Существует ошибка в исходном коде, когда pathIn содержит пробелы в Windows. QProcess::startDetached автоматически укажет параметр, если он содержит пробелы. Однако Windows Explorer не распознает параметр, заключенный в кавычки, и вместо этого откроет место по умолчанию. Попробуй себя в командной строке с 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); 
+1

Я проверил код в сообщении в блоге, которое вы связали. Он работает (по крайней мере, в Mac OS X). –

+0

Если вам нужно открыть путь, содержащий пробелы, вы можете использовать что-то вроде этого: QProcess :: startDetached (QString ("explorer/select, \"% 1 \ ""). Arg (QDir :: toNativeSeparators (path))); – dismine

+0

Прежде чем попытаться перенести все это в PyQt, можете ли вы подтвердить, что он работает в Linux, выбор файлов и все? Комментарий: «Мы не можем выбрать файл здесь, потому что ни один браузер не поддерживает его», не кажется многообещающим. –

4

Открыть файл в 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); 

} 
+1

Приятно, если вы используете операционную систему, которая поставляется с проводником Windows, но большинство моих пользователей предпочитают избегать таких проблем. ☺ –

+0

Немного бит для Windows, но отлично работает, спасибо! – mrexodia

2

Вот код, который я отправил с основываясь на результатах предыдущего ответа. Эта версия не зависит от других методов в 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())); 
} 
+0

Мне нравится этот подход, потому что он прост. Я портировал это на python/PyQt5, посмотрите [здесь] (https://pastebin.com/xrcE3a2L). – normanius

+1

Что касается MacOS: Обратите внимание, что 'путь' должен быть абсолютным. Можно подавить выходные сообщения из 'osascript', просто добавив инструкцию' return'. – normanius

+0

И еще одно: просто выполнение 'open dirPath' будет еще более простым в MacOS, но оно не выделяет файл, если' path' был фактически файлом. – normanius

Смежные вопросы