2010-08-16 23 views
35

¿Es posible abrir una carpeta en Windows Explorer/OS X Finder y luego seleccionar/resaltar un archivo en esa carpeta y hacerlo en una plataforma cruzada ¿camino? En este momento, hago algo así comoCómo "Revelar en Finder" o "Mostrar en Explorer" con Qt

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

donde path es una ruta completa a la carpeta que desea abrir. Obviamente, esto solo abrirá la carpeta, y tendré que rastrear el archivo que necesito manualmente. Esto es un problema cuando hay miles de archivos en esa carpeta.

Si hago una ruta de acceso a un archivo específico en esa carpeta, entonces ese archivo está abierto con la aplicación predeterminada para ese tipo de mime, y eso no es lo que necesito. En cambio, necesito la funcionalidad equivalente a "Revelar en el buscador" o "Mostrar en el Explorador".

+0

Para aclarar: ¿Quieres decir como cuando se hace clic en un "Reveal en Buscador "o" Mostrar en el Explorador "elemento de menú? –

+0

@Austin Sí, lo que quise decir es exactamente algo así como "Revelar en Finder" o "Mostrar en Explorer" – nnc

Respuesta

5

Probablemente puede usar QFileDialog::getOpenFileName para obtener el nombre del archivo. La documentación está disponible here .. La función anterior se devolver la ruta completa incluyendo el nombre del archivo y su extensiónsi alguno ..

entonces usted puede dar

QDesktopServices::openUrl(path);

para abrir el el archivo en su aplicación predeterminada, donde path será QString devuelto por QFileDialog::getOpenFileName.

creo que sirve ..

+3

gracias por la respuesta, pero eso no es lo que necesito. Actualicé la pregunta para tratar de aclarar eso. Lo que necesito es la funcionalidad "Revelar en el buscador" o "Mostrar en el explorador". – nnc

+0

El método openUrl() de QDesktopServices realmente muestra un archivo/directorio en el explorador. ¿Prefijo "file: ///" en su cadena de ruta? – Stradivari

+1

@liaK: El OP solo quiere que el archivo ** muestre ** en el explorador, no ** lo abra **. Su método intentará ** abrir ** el archivo en sí. – diverger

33

Qt Creator tiene esta funcionalidad, es trivial para copiarlo:

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 
} 

Otro, entrada de blog relacionada (con el código más simple, no he probado de modo que pueda 't comment), es this.

Editar:

Hay un error en el código original cuando Pathin contiene espacios en Windows. QProcess::startDetached citará automáticamente un parámetro si contiene espacios. Sin embargo, Windows Explorer no reconocerá un parámetro envuelto entre comillas, y en su lugar abrirá la ubicación predeterminada. Inténtelo usted mismo en la línea de comandos de 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" 

Por lo tanto,

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

se cambia a

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

Probé el código en la publicación de blog que enlazó. Funciona (al menos en Mac OS X). –

+0

Si necesita abrir la ruta que contiene espacios, puede usar algo como esto: QProcess :: startDetached (QString ("explorer/select, \"% 1 \ "") arg (QDir :: toNativeSeparators (path))); – dismine

+0

Antes de tratar de portar todo eso a PyQt, ¿puede confirmar que funciona en Linux, selección de archivos y todo? El comentario "no podemos seleccionar un archivo aquí, porque ningún buscador de archivos realmente lo admite" no suena prometedor. –

4

Abrir el archivo en el Explorador de Windows (no el navegador)

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

Agradable si está usando un sistema operativo que viene con Windows Explorer, pero la mayoría de mis usuarios prefieren evitarlo. ☺ –

+0

Un poco de un truco específico de Windows, pero funciona muy bien, ¡gracias! – mrexodia

2

Aquí está el código que fui con basado en las entradas de una respuesta previa. Esta versión no depende de otros métodos en Qt Creator, acepta un archivo o directorio, y tiene una caída hacia atrás el modo de gestión de errores y otras plataformas:

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

Me gusta este enfoque porque es sencillo. Lo porté a python/PyQt5, eche un vistazo [aquí] (https://pastebin.com/xrcE3a2L). – normanius

+1

En cuanto a MacOS: tenga en cuenta que 'ruta' tiene que ser absoluta. Uno puede suprimir mensajes de salida de 'osascript' simplemente agregando una instrucción' return'. – normanius

+0

Y una cosa más: simplemente ejecutar 'abrir dirPath' sería aún más sencillo en MacOS, pero no resalta el archivo si' path' era en realidad un archivo. – normanius