2010-08-16 9 views
35

Czy można otworzyć folder w Eksploratorze Windows/OS X Finder, a następnie wybrać/zaznaczyć jeden plik w tym folderze i zrobić to na platformie droga? Teraz, zrobić coś jakJak "Reveal in Finder" lub "Show in Explorer" z Qt

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

gdzie path jest pełną ścieżkę do folderu chcę otworzyć. Oczywiście, to po prostu otworzy folder i będę musiał wyśledzić plik, który potrzebuję ręcznie. Jest to problem, gdy w tym folderze znajdują się tysiące plików.

Jeśli utworzę ścieżkę do określonego pliku w tym folderze, to ten plik jest otwarty z domyślną aplikacją dla tego typu MIME, a to nie jest to, czego potrzebuję. Zamiast tego potrzebuję funkcjonalności równoważnej "Reveal in Finder" lub "Show in Explorer".

+0

do wyjaśnienia: Masz na myśli po kliknięciu „Reveal w Finder "lub" Pokaż w Eksploratorze "element menu? –

+0

@Austin Tak, chodzi mi o to, że jest dokładnie coś takiego jak "Reveal in Finder" lub "Show in Explorer" – nnc

Odpowiedz

5

Prawdopodobnie można użyć nazwy QFileDialog::getOpenFileName, aby uzyskać nazwę pliku. Dokumentacja jest dostępna here .. Powyższa funkcja jeśli jakiekolwiek zwróci pełną ścieżkę wraz z nazwą pliku i jego rozszerzenie..

Wtedy można dać

QDesktopServices::openUrl(path);

aby otworzyć plik w domyślnej aplikacji, gdzie path będzie zwrócony przez QFileDialog::getOpenFileName.

Nadzieja to pomaga ..

+3

dzięki za odpowiedź, ale to nie jest to, czego potrzebuję. Zaktualizowałem to pytanie, aby spróbować to wyjaśnić. Potrzebuję funkcji "Reveal in Finder" lub "Show in Explorer". – nnc

+0

Metoda openUrl() - metoda QDesktopServices pokazuje plik/katalog w eksploratorze. Czy dodałeś ciąg "file: ///" do łańcucha znaków? – Stradivari

+1

@liaK: OP właśnie chce pliku ** pokazać ** w eksploratorze, a nie ** otworzyć ** go. Twoja metoda spróbuje ** otworzyć ** sam plik. – diverger

33

Qt Creator ma tę funkcję, to jest trywialne, aby ją skopiować:

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 
} 

Innym, związanych blogu (z prostszej kodu, ja nie próbowałem go więc mogę komentarz), jest this.

Edit:

Jest to błąd w oryginalnym kodzie kiedy pathIn zawiera spacje w systemie Windows. QProcess::startDetached automatycznie przytoczy parametr, jeśli zawiera spacje. Jednak Eksplorator Windows nie rozpoznaje parametru zawiniętego w cudzysłowy i zamiast niego otworzy domyślną lokalizację. Spróbuj sam w wierszu poleceń systemu 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" 

Zatem

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

jest zmieniana na

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

Testowałem kod w blogu, który łączyłeś. To działa (przynajmniej na Mac OS X). –

+0

Jeśli potrzebujesz otworzyć ścieżkę zawierającą spacje, możesz użyć czegoś takiego: QProcess :: startDetached (QString ("explorer/select, \"% 1 \ ""). Arg (QDir :: toNativeSeparators (path))); – dismine

+0

Zanim spróbuję przenieść to wszystko do PyQt, czy możesz potwierdzić, że działa on pod Linuksem, wybierając plik i wszystko? Komentarz "nie możemy tu wybrać pliku, ponieważ przeglądarka plików naprawdę go obsługuje" nie brzmi obiecująco. –

4

Otwórz plik w programie Windows Explorer (nie przeglądarki)

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

Przyjemnie, jeśli używasz systemu operacyjnego z Eksploratorem Windows, ale większość moich użytkowników woli tego unikać. ☺ –

+0

Trochę hackowania specyficznego dla systemu Windows, ale działa świetnie, dzięki! – mrexodia

2

Oto kod, który wybrałem na podstawie danych wejściowych z poprzedniej odpowiedzi. Wersja ta nie zależy od innych metod w Qt Creator, akceptuje pliku lub katalogu i ma cofać tryb obsługi błędów i innych platform:

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

Podoba mi się to podejście, ponieważ jest proste. Przeniosłem to do Pythona/PyQt5, zajrzyj [tutaj] (https://pastebin.com/xrcE3a2L). – normanius

+1

Co do MacOS: Zwróć uwagę, że 'ścieżka' musi być absolutna. Można wyłączyć komunikaty wyjściowe z 'osascript', po prostu dodając instrukcję' return'. – normanius

+0

I jeszcze jedno: samo wykonanie 'open dirPath' będzie jeszcze prostsze na MacOS, ale nie podświetli pliku, jeśli' path' jest w rzeczywistości plikiem. – normanius