2010-08-16 33 views
35

Ist es möglich, einen Ordner in Windows Explorer/OS X Finder zu öffnen und markieren/markieren Sie eine Datei in diesem Ordner, und tun Sie es in einer plattformübergreifenden Weg? Gerade jetzt, ich mache so etwas wieWie "im Finder anzeigen" oder "im Explorer anzeigen" mit Qt

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

wo path einen vollständigen Pfad ist in den Ordner I öffnen möchten. Offensichtlich wird dadurch nur der Ordner geöffnet, und ich muss die Datei, die ich brauche, manuell aufspüren. Dies ist ein kleines Problem, wenn sich in diesem Ordner Tausende von Dateien befinden.

Wenn ich es einen Pfad zu bestimmten Datei in diesem Ordner machen, dann ist diese Datei mit Standard-Anwendung für diesen Mime-Typ geöffnet, und das ist nicht was ich brauche. Stattdessen benötige ich die Funktionalität, die "Im Finder anzeigen" oder "Im Explorer anzeigen" entspricht.

+0

Zur Klarstellung: Sie meinen mögen, wenn Sie ein „Klick in Reveal Finder "oder" Show in Explorer "Menüpunkt? –

+0

@Austin Ja, was ich meinte, ist genau so etwas wie "Reveal in Finder" oder "Show in Explorer" – nnc

Antwort

5

Wahrscheinlich können Sie QFileDialog::getOpenFileName verwenden, um den Dateinamen zu erhalten. Die Dokumentation ist here .. Die obige Funktion wird den vollständigen Pfad zurückkehren einschließlich des Dateinamens und seiner Erweiterungwenn jeder ..

Dann können Sie

QDesktopServices::openUrl(path);

geben die öffnen die Datei in der Standardanwendung, wobei path die QString ist, die von QFileDialog::getOpenFileName zurückgegeben wird.

Hoffe, es hilft ..

+3

danke für die Antwort, aber das ist nicht was ich brauche. Ich habe die Frage aktualisiert, um das zu klären. Was ich brauche, ist "Reveal in Finder" oder "Show in Explorer" -Funktionalität. – nnc

+0

Die openUrl() - Methode von QDesktopServices zeigt tatsächlich eine Datei/ein Verzeichnis im Explorer an. Haben Sie "file: ///" auf Ihrer Pfadzeichenfolge vorangestellt? – Stradivari

+1

@liaK: Das OP möchte nur die Datei ** show ** im Explorer, nicht ** öffnen ** es. Ihre Methode versucht ** die Datei ** selbst zu öffnen. – diverger

33

Qt Creator diese Funktionalität hat, ist es trivial ist es zu kopieren:

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 
} 

Eine weitere, verwandte Blog-Post (mit einfacher Code, habe ich es nicht versucht, so kann ich 't kommentieren), ist this.

Edit:

Es ist ein Fehler in dem ursprünglichen Code, wenn pathIn Räume unter Windows enthält. QProcess::startDetached wird automatisch einen Parameter angeben, wenn er Leerzeichen enthält. Windows Explorer erkennt einen in Anführungszeichen eingeschlossenen Parameter jedoch nicht und öffnet stattdessen den Standardspeicherort. Probieren Sie es selbst in der Windows-Kommandozeile:

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" 

So

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

geändert, um

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

Ich habe den Code in dem von Ihnen verlinkten Blogpost getestet. Es funktioniert (zumindest unter Mac OS X). –

+0

Wenn Sie einen Pfad öffnen müssen, der Leerzeichen enthält, können Sie Folgendes verwenden: QProcess :: startDetached (QString ("explorer/select, \"% 1 \ ""). Arg (QDir :: toNativeSeparators (Pfad))); – dismine

+0

Bevor ich versuche, all das auf PyQt zu portieren, können Sie bestätigen, dass es in Linux funktioniert, Dateiauswahl und alles? Der Kommentar "Wir können hier keine Datei auswählen, weil kein Dateibrowser dies wirklich unterstützt" klingt nicht vielversprechend. –

4

Datei öffnen in Windows Explorer (nicht Browser)

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

Schön, wenn Sie ein Betriebssystem verwenden, das mit Windows Explorer geliefert wird, aber die meisten meiner Benutzer bevorzugen, diese zu vermeiden. ☺ –

+0

Ein bisschen von einem Windows-spezifischen Hack aber funktioniert gut, danke! – mrexodia

2

Hier ist der Code, mit dem ich ging basierend auf den Eingaben von einer vorherigen Antwort. Diese Version nicht auf andere Methoden in Qt Creator abhängt, akzeptiert eine Datei oder ein Verzeichnis, und hat eine Fallback-Modus für die Fehlerbehandlung und anderen Plattformen:

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

Ich mag diesen Ansatz, weil es einfach ist. Ich habe dies nach Python/PyQt5 portiert, siehe [hier] (https://pastebin.com/xrcE3a2L). – normanius

+1

Wie bei MacOS: Beachten Sie, dass 'path' absolut sein muss. Man kann Ausgabemeldungen von "osascript" unterdrücken, indem man einfach eine 'return'-Anweisung hinzufügt. – normanius

+0

Und noch etwas: Die Ausführung von 'open dirPath' wäre auf MacOS noch einfacher, aber es hebt die Datei nicht hervor, wenn' path' tatsächlich eine Datei ist. – normanius