2017-10-10 605 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 –