0
votes

I have made a qml file named fileDialog.qml and which use element FileDialog{} available from qt5

http://qt-project.org/doc/qt-5.1/qtquickdialogs/qml-qtquick-dialogs1-filedialog.html.

Whenever i need the location of resource i want to use fileDialog.qml as component and set all the properties like title, filter etc. These are working fine but when i tried to use id.fileUrl then no response. details are given below.

The file fileDialog.qml is

import QtQuick 2.1
import QtQuick.Dialogs 1.0

FileDialog {
    id: fileDialog
    objectName: "fileBrowser"
    title: "Add New Layer"
    visible: false
    property alias selectedFilename: fileDialog.fileUrls

    onAccepted: {
        console.log("You chose: " + fileDialog.fileUrls)//--------         (1)
    }
    onRejected: {
        console.log("Canceled")
   }
    //Component.onCompleted: visible = true
}

Now using this as component when Browse(an item in QML to be used like button) button is clicked then i am performing following steps.

onClicked: {

 //Default Values fileDialog.{selectExisting = true, selectFolder = false}
 fileDialog.title = "Add New Image"
 //fileDialog1.selectMultiple = true
 fileDialog.nameFilters = ["Image File (*.png *.jpg *.bmp)"]


 //fileDialog.fileUrls
 //string path

 fileDialog.visible = true
 console.log(" Image chosen: " + fileDialog.fileUrl + " in image")//---  (2)


}

The line (1) is working fine but but (2) is not working. The output of (2) line in console is just Image chosen: in image.

I don't understand what am I doing wrong here, because when I am setting other(like title, filer) property of component fileDialog its working but not for the fileUrl or fileUrls.

Please somebody suggest how to get the fileUrl when using it as component.

Thanks,

3

3 Answers

1
votes

Just a try. From documentation, you can see that fileUrl property is only set if you make a single file selection. So you are right to expect it to be setted by your FileDialog

The problem is that you try to display fileUrl before the FileDialog is closed I think. Showing a modal dialog probably don't block your function execution.

As you do in your base component fileDialog.qml, you can put a handler on onAccepted. When your handler will be called, fileUrl property will be available.

edit:

Browse {
    id: browser

    signal fileChosen

    FileDialog {
        id: fileDialog

        //configure your fileDialog here
        //...

        //emit parent signal when done
        onAccepted: browser.fileChosen();
    }

    onClicked: {
        fileDialog.open();
    }

    onFileChosen: {
        //fileUrl should be available here
        console.log(fileDialog.fileUrl);
    }
}
2
votes

I think what you're trying to do is creating a special FileDialog component that fits your needs.

First, let's call this component "MyFileFialog" saved in MyFileDialog.qml.

// MyFileDialog.qml
import QtQuick 2.0
import QtQuick.Dialogs 1.0

Item {
    id: root
    property alias title: qmlFileDialog.title
    property alias fileUrl: qmlFileDialog.fileUrl
    property alias fileUrls: qmlFileDialog.fileUrls

    signal accepted()
    signal rejected()

    function open() { qmlFileDialog.open() }
    function close() { qmlFileDialog.close() }

    FileDialog {
        id: qmlFileDialog
        modality: Qt.WindowModal
        nameFilters: ["Image File (*.png *.jpg *.bmp)"]

        onAccepted: root.accepted()
        onRejected: root.rejected()
    }
}

There are now a bunch of connections between MyFileDialog and FileFialog:

  • modality and nameFilters are fixed
  • title, fileUrl, fileUrls are passed between both components
  • when the FileDialog is accepted or rejected, the MyFileDialog will be as well
  • when you open() or close() your MyFileDialog, the inner FleDialog will open or close

Now that you have your very own MyFileDialog, you can use it:

Button {
    text: "open"

    MyFileDialog {
        id: saveFileDialog
        title: qsTr("Save to ...")
        onRejected: {
            console.log("Canceled")
        }
        onAccepted: {
            console.log("File selected: " + fileUrl)
        }
    }

    onClicked: {
        saveFileDialog.open()
    }
}
0
votes

I got a solution after reading the answer of @jbh whose answer helps in accessing fileUrl outside FileDialog{} element in same qml file but that's not an answer to my question.

Element FileDialog{} have an signal accepted so we use this signal to connect to a method and then access the fileUrl or Urls. This how fileBrowser.qml look like.

import QtQuick 2.1
import QtQuick.Dialogs 1.0

FileDialog {
    id: fileDialog
    objectName: "fileBrowser"
    title: "Add New Layer"
    visible: false
    //property alias selectedFilename: fileDialog.fileUrls
//    signal fileChosen
//    onAccepted: {
//        console.log("You chose: " + fileDialog.fileUrls)
//        fileChosen();
//    }
    onRejected: {
        console.log("Canceled")
    }
    //Component.onCompleted: visible = true
}

onAccepted slot above is commented and we use accepted signal to access fileUrl.

This is how a qml file will look when using fileBrowser.qml as component whenever file dialog is required.

Item{
id: popup

  Rectangle{
    id: browse button

    // properties setting for construction a button such as width, color, mouse area, states, etc.. 
    // the method where we can use the URLS

    function dialogAccepted(){

      fileDialog.accepted.disconnect(dialogAccepted)
      filePath.text = Qt.resolvedUrl( fileDialog.fileUrl ).toString()// to set the text in text field
      console.log("You Chose in elev: " + fileDialog.fileUrl)
      //browseButtonClicked(checkBox.checked)

     }

     onClicked: {
          //Default Values fileDialog.{selectExisting = true, selectFolder = false}

          fileDialog.title = "Add New Image"
          //fileDialog1.selectMultiple = true
          fileDialog.nameFilters = ["Image File (*.png *.jpg *.bmp)"]


          fileDialog.visible = true
          fileDialog.accepted.connect(dialogAccepted)
      }  


   }

}

well, this worked for me but i am still facing problem with how to resolve Url when multiple file is selected and how to send it to c++ file so that it is accepted.