How to display different image with FileDialog?
-
Hi, I want to display image files with JS using createcomponent in a list model. I access the folder with FileDialog and the source property of my Image object is source: filedialog.fileUrl. I'm importing it to ListModel and UI using imagemodels.append() . My problem is: i am viewing the first photo 2nd and 3rd etc. I also view photos. So photos appear when FileDialog is triggered. But when I trigger it for the 3rd or 4th time, all 4 photos are the same, that is, it opens the fileUrl of the last photo. How can I get past this?
JS Functions
function addImage() { CreateObject.create("AddImage.qml", root, imageAdded); }
function imageAdded (obj, source) { imagemodels.append({"obj": obj, "source": source}) }
var _component; var _callback; var _parent; var _source; function create(source, parent, callback) { _parent = parent; _callback = callback; _source = source; _component = Qt.createComponent(source); if (_component.status === Component.Ready || _component.status === Component.Error) createDone(); else _component.statusChanged.connect(createDone); } function createDone() { if (_component.status === Component.Ready) { var obj = _component.createObject(_parent); if (obj != null) _callback(obj, _source); else console.log("Error object: " + _source); _component.destroy(); } else if (_component.status === Component.Error) console.log("Error component: " + component.errorString()); }
My AddImage.qml
import QtQuick 2.0 import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 import QtQuick.Window 2.0 import io.qt.examples.texteditor 1.0 import QtQuick 2.5 Image{ width:80 height:80 fillMode: Image.PreserveAspectFit asynchronous: true source: filedialog.fileUrl }
My FileDialog;
FileDialog { id: filedialog nameFilters: ["Image files (*.png *.jpg)"] onAccepted: { TddImage() console.log("Accepted Files:"+ fileUrls) } }
-
@tacdin It's really hard to see what is going on with your code, but I think the issue is that your
Image
source
is bound directly tofileDialog.fileUrl
. Therefore every image will show the most recently selected file.Why don't you pass the selected url to
addImage
fromonAccepted
?I am not sure how your
CreateObject
stuff works, but if that is usingComponent.createObject
, you can pass thesource
property in as an argument. (See thecreateObject
documentation.) -
I'll assume single file select here for simplicity. I would concentrate on getting this working and then extend to multiple files.
onAccepted: { addImage(fileUrl); console.log("Accepted File:"+ fileUrl); }
Then change
addImage
to accept a parameter:function addImage(file) { // I'm not sure what you are doing in here, but assuming you are using `createObject` somehow: ... component.createObject(parent, {'source': file}); }
-
@Bob64
Now im trying also my codes are below;createobject.js
var _component; var _callback; var _parent; var _source; function create(source, parent, callback) { _parent = parent; _callback = callback; _source = source; _component = Qt.createComponent(source); if (_component.status === Component.Ready || _component.status === Component.Error) createDone(); else _component.statusChanged.connect(createDone); } function createDone() { if (_component.status === Component.Ready) { var obj = _component.createObject(_parent); if (obj != null) _callback(obj, _source); else console.log("Error object: " + _source); _component.destroy(); } else if (_component.status === Component.Error) console.log("Error component: " + component.errorString()); }
addImage() function
function addImage() { CreateObject.create("AddImage.qml", root, imageAdded); }
-
-
@tacdin at the moment, I am not sure exactly what is not working for you. Did you change your code so that the
source
value is passed down tocreateObject
and changeaddImage
to receive a file argument? What is the outcome?One thing you could do if you have modified in this way is to temporarily take
FileDialog
out of the picture, and try to get it working with hard-coded paths.Something else that occurred to me is that I wonder if you would be better to construct your
Image
s on the fly in yourListView
delegate, leaving the model purely to store the data (the file paths). This would avoid all of thecreateObject
stuff. There might be performance reasons for what you are doing - I am not an expert by any means - but you might at least be able to get something working more easily.Have you seen this example on StackOverflow which is not a million miles from what I am suggesting:
https://stackoverflow.com/questions/51797938/show-list-of-image-by-listview-in-qml
Note that the model in this example is just the file list from the
FileDialog
. In your case, you might still want to have a simpleListModel
that the dialog would update, but, as I suggested earlier, you could start off hard coding the paths:ListModel { ListElement { filePath: "/path/to/image2.jpg" } ListElement { filePath: "/path/to/image2.jpg" } ...
-
@Bob64 Thanks for your suggestions. I'll post the result here after I try again.
"Did you change your code so that the source value is passed down to createObject and change addImage to receive a file argument?"
I've tried but something is wrong and I'm having trouble understanding why.
-
@Bob64 Of course I will, I'm editing it now to make it more readable.
Also, I have one more question. new hurdle in front of me: I want to get these photos, texts etc. to be displayed in PDF. I need to convert these information to PDF. i.e. a button to convert from view to PDF(like export as PDF). Do you have a suggestion for this?