2017-10-10 313 views
1

我想将上次使用的文件夹存储在qml文件对话框中(使用Qt版本5.6)。我这样做的方式是通过具有url属性lastUsedFolder这样QSettings:如何从QML中的UNC路径设置FileDialog的文件夹?

///////////// 
/// myApp.qml 
///////////// 

import QtQuick 2.3 
import QtQuick.Dialogs 1.1 
import Qt.labs.settings 1.0 

Settings { 
    id: settings 
    property url lastUsedFolder; 
} 

FileDialog { 
    id: openDialog 
    onVisibleChanged: 
    { 
     if(visible && myApp.doesFolderStillExist(settings.lastUsedFolder)) 
     { 
      console.log("setting folder of dialog") 
      folder = settings.lastUsedFolder 
      console.log(folder) 
     } 
    } 
    onAccepted: 
    { 
     console.log("saving folder: " + folder) 
     settings.lastUsedFolder = folder; 
    } 
} 

///////////// 
/// myApp.cpp 
///////////// 
bool myApp::doesFolderStillExist(QUrl folderUrl) 
{ 
    QFileInfo folder(folderUrl.toLocalFile()); 
    if (folder.exists()) 
     return true; 
    return false; 
} 

这适用于本地文件时做得不够好,但确实在通过UNC格式路径寻址远程计算机使用时,而不是文件如\\myRemotePC.somewhere.com\myData\

如果我浏览到这个地址并接受对话框,该文件夹存储感谢onAccepted方法和控制台打印saving folder: file://myRemotePC.somewhere.com/myData。然后当我再次打开对话框时,onVisibleChanged触发器。 doesFolderStillExists方法会看到文件夹 - QUrl.toLocalFile似乎正常工作 - 并且settings.lastUsedFolder中存储的路径仍与存储的路径相同。但随后对分配给folder属性与以下错误行应用程序崩溃(Windows 7中;最后控制台打印仅仅是“设置对话框的文件夹”):

QWindowsNativeFileDialogBase::shellItem: SHCreateItemFromParsingName(file:///myRemotePC.somewhere.com/myData) failed()

换句话说,当我尝试使用与之前读取的完全相同的值来设置对话框的文件夹属性时,它崩溃......并且让我困惑。

不知道它是否重要,但我注意到一个奇怪的事情是该错误消息在file:之后有三个正斜杠,而我设置为该文件夹的路径只有两个。我试图修改以各种方式路径:

  • 如果file:被完全省略,在对话框中的默认位置打开,可能无法解析以有意义的方式地址 - 这是一种预期
  • 不管有多少个斜杠我添加或删除file:后,会出现相同的错误消息,总是在所示路径有三条斜杠

我希望这将导致我能够存储并重新任何意见 - 以“本地”和“可用”方式在FileDialog中使用上次使用的文件夹UNC路径,即使它以不同于我们当前使用的方式完成。

回答

2

这似乎是来自Qt的错误。 QFileDialog尝试在一个糟糕的方式来“纠正”您的URI,因为如果你转换像一个UNC路径“\ myRemotePC.somewhere.com \ myData的\”到URI,它会给你“文件://myRemotePC.somewhere.com/myData“,这一部分是正确的,但从QFileDialog的角度来看,您尝试获取本地文件夹。

我尝试用原始字符串或URL喂QFileDialog但QFileDialog坚持将路径转换。

如果你需要一个解决方法,从调用C++ QFileDialog,它像UNC路径字符串路径工作。

另一种解决方法,连接外部文件夹作为网络驱动器。

对不起,我可怜的英语^^

如果有人想快速尝试。

import QtQuick 2.6 
import QtQuick.Window 2.2 
import QtQuick.Dialogs 1.2 
import Qt.labs.settings 1.0 

Window { 
Component.onCompleted: { 
    openDialog.open(); 
} 

FileDialog { 
    id: openDialog 
    selectFolder: true 
    Component.onCompleted: folder = settings.lastFolderURL; 
    onVisibleChanged: 
    { 
     console.log("lastFolder as string " + settings.lastFolderString); 
     console.log("lastFolder as URL " + settings.lastFolderURL); 
    } 
    onAccepted: 
    { 
     console.log("Selected folder : " + folder) 
     settings.lastFolderString = folder; 
     settings.lastFolderURL = folder; 
    } 
} 

Settings { 
    id: settings 
    property string lastFolderString ; 
    property url lastFolderURL; 
} 
} 
+0

从C++端执行对话框可能是一个选项,虽然是一个非常丑陋的,我希望有更好的方法,但谢谢。连接远程位置作为驱动器工作,但并不能解决崩溃问题 - 人们会不断写信给我们的支持,即当他们使用网络驱动器时(并且在我的领域,人们使用网络驱动器)软件崩溃。我可以检查路径是否是UNC,如果是,则不要“记住”,但这对用户来说有点方便。 – tomj

+0

但是,否则我同意你的发现 - 它看起来像FileDialog在onFolderChanged期间正在做一些类型的路径转换/更正,但没有考虑到UNC路径:( – tomj

+0

我已经提交了bug https:// bugreports。 qt.io/browse/QTBUG-63710 –