Creating two main.qml files, shared codebase
-
Hi,
It's written in the "File Selector" note on the page you linked. You have to create one or more folders with the format "+selector" where your replace selector by the appropriate name and in your can your secondary main.qml file.
I created a folder named +selector in the project's directory and put a main.qml file with this content (related to the project talked about in the link):
import QtQuick import QtQuick.Controls import QtQuick.Controls.Material ImageViewerWindow { id: window width: 360 height: 520 Drawer { id: drawer width: Math.min(window.width, window.height) / 3 * 2 height: window.height ListView { focus: true currentIndex: -1 anchors.fill: parent delegate: ItemDelegate { width: parent.width text: model.text highlighted: ListView.isCurrentItem onClicked: { drawer.close() model.triggered() } } model: ListModel { ListElement { text: qsTr("Open ...") triggered: function () { fileOpenDialog.open() } } ListElement { text: qsTr("About ...") triggered: function() {aboutDialog.open() } } } ScrollIndicator.vertical: ScrollIndicator {} } } header: ToolBar { Flow { anchors.fill: parent ToolButton { text: qsTr("Open") icon.name: "document-open" onClicked: window.openFileDialog() } } } }
The ImageViewerWindow.qml file contains:
import QtQuick import QtQuick.Controls import Qt.labs.platform as Labs ApplicationWindow { visible: true title: qsTr("Image Viewer") function openFiledialog() { fileDialog.open() } function openAboutDialog() { aboutDialog.open() } background: Rectangle { color: "darkGray" } Image { id: image anchors.fill: parent fillMode: Image.PreserveAspectFit asynchronous: true } Labs.FileDialog { id: fileOpenDialog title: "Select an image file" folder: Labs.StandardPaths.writableLocation(Labs.StandardPaths.DocumentsLocation) nameFilters: [ "Image files (*.png *.jpeg *.jpg)" ] onAccepted: image.source = fileOpenDialog.currentFile } Dialog { id: aboutDialog title: qsTr("About") Label { anchors.fill: parent text: qsTr("QML Image Viewer\nA part of the QmlBook\nhttp://qmlbook.org") horizontalAlignment: Text.AlignHCenter } standardButtons: Dialog.Ok } }
And finally, the main main.qml file has this code:
import QtQuick import QtQuick.Controls import QtQuick.Controls.Material ImageViewerWindow { id: window width: 360 height: 520 Drawer { id: drawer width: Math.min(window.width, window.height) / 3 * 2 height: window.height ListView { focus: true currentIndex: -1 anchors.fill: parent delegate: ItemDelegate { width: parent.width text: model.text highlighted: ListView.isCurrentItem onClicked: { drawer.close() model.triggered() } } model: ListModel { ListElement { text: qsTr("Open ...") triggered: function () { fileOpenDialog.open() } } ListElement { text: qsTr("About ...") triggered: function() {aboutDialog.open() } } } ScrollIndicator.vertical: ScrollIndicator {} } } header: ToolBar { Flow { anchors.fill: parent ToolButton { text: qsTr("Open") icon.name: "document-open" onClicked: window.openFileDialog() } } } }
Have I done the task right up to here, please?
-
If you named the folder literally "+selector" then no, that part is wrong. "selector" must be replaced with an adequate value as explained in the link you posted.
You need to explain what exactly you want to accomplish because at this time it's unclear what you want to use the File Selector concept for.
-
If you named the folder literally "+selector" then no, that part is wrong. "selector" must be replaced with an adequate value as explained in the link you posted.
You need to explain what exactly you want to accomplish because at this time it's unclear what you want to use the File Selector concept for.
"selector" must be replaced with an adequate value
What does that mean? :(
as explained in the link you posted.
I read the section a couple of time but can't understand it completely sadly! :(
You need to explain what exactly you want to accomplish
I've nothing in my mind for that except learning what the link in that section tries to teach. It's the first time I encounter such a feature. I merely want to learn that for future uses.
The link says:
The two main.qml files are placed in the file system as shown below. This lets the file selector that the QML engine automatically creates pick the right file. By default, the Fusion main.qml is loaded. If the android selector is present, then the Material main.qml is loaded instead. -
If you name your folder "+android", the the main.qml file from that folder will be loaded when running your application on that platform.
-
If you name your folder "+android", the the main.qml file from that folder will be loaded when running your application on that platform.
Here's my
main.cpp
:
And other files:
+android -> main.qml
:import QtQuick import QtQuick.Controls ImageViewerWindow { id: window width: 640 height: 480 menuBar: MenuBar { Menu { title: qsTr("&File") MenuItem { text: qsTr("&Open...") icon.name: "document-open" onTriggered: window.openFileDialog() } } Menu { title: qsTr("&Help") MenuItem { text: qsTr("&About...") onTriggered: window.openAboutDialog() } } } header: ToolBar { Flow { anchors.fill: parent ToolButton { text: qsTr("Open") icon.name: "document-open" onClicked: window.openFileDialog() } } } }
ImageViewerWindow.qml
:import QtQuick import QtQuick.Controls import Qt.labs.platform as Labs ApplicationWindow { visible: true title: qsTr("Image Viewer") function openFiledialog() { fileDialog.open() } function openAboutDialog() { aboutDialog.open() } background: Rectangle { color: "darkGray" } Image { id: image anchors.fill: parent fillMode: Image.PreserveAspectFit asynchronous: true } Labs.FileDialog { id: fileOpenDialog title: "Select an image file" folder: Labs.StandardPaths.writableLocation(Labs.StandardPaths.DocumentsLocation) nameFilters: [ "Image files (*.png *.jpeg *.jpg)" ] onAccepted: image.source = fileOpenDialog.currentFile } Dialog { id: aboutDialog title: qsTr("About") Label { anchors.fill: parent text: qsTr("QML Image Viewer\nA part of the QmlBook\nhttp://qmlbook.org") horizontalAlignment: Text.AlignHCenter } standardButtons: Dialog.Ok } }
main.qml
:import QtQuick import QtQuick.Controls import QtQuick.Controls.Material ImageViewerWindow { id: window width: 360 height: 520 Drawer { id: drawer width: Math.min(window.width, window.height) / 3 * 2 height: window.height ListView { focus: true currentIndex: -1 anchors.fill: parent delegate: ItemDelegate { width: parent.width text: model.text highlighted: ListView.isCurrentItem onClicked: { drawer.close() model.triggered() } } model: ListModel { ListElement { text: qsTr("Open ...") triggered: function () { fileOpenDialog.open() } } ListElement { text: qsTr("About ...") triggered: function() {aboutDialog.open() } } } ScrollIndicator.vertical: ScrollIndicator {} } } header: ToolBar { Flow { anchors.fill: parent ToolButton { text: qsTr("Open") icon.name: "document-open" onClicked: window.openFileDialog() } } } }
When I run the project and click on the Open button, I get this error:
TypeError: Property 'openFileDialog' of object ImageViewerWindow_QMLTYPE_13(0x222d1303030) is not a function(related to line 50 of main.qml,
onClicked: window.openFileDialog()
) -
function openFiledialog() { fileDialog.open() }
Shouldn't it be "fileOpenDialog.open()" ?
-
-
The issue is that you have an id that is the same as the function name with just two words reversed. Hence my question.
-
The issue is that you have an id that is the same as the function name with just two words reversed. Hence my question.
Yeah, right. I fixed it, thanks.
One question: in main
main.qml
file we have:import QtQuick import QtQuick.Controls import QtQuick.Controls.Material ImageViewerWindow { // ... model: ListModel { ListElement { text: qsTr("Open ...") triggered: function() { openFiledialog() } } ListElement { text: qsTr("About ...") triggered: function() { openAboutDialog() } } } //... }
Why can't we use triggered like this:
triggered: openFiledialog()
? That's calling the function directly instead of declaring a function just for that purpose?My second question is: how to run the project with different styles, please?
I mean, how to run the project for the Fusion style and how to for the Material style?
I think the use case of this feature (shared codebase) is also this. -
Because it's a model and thus there's no GUI interaction there.
As for switching the selector, it's again described in the article you linked in your post. Use the QT_FILE_SELECTORS environment variable.
-
Because it's a model and thus there's no GUI interaction there.
As for switching the selector, it's again described in the article you linked in your post. Use the QT_FILE_SELECTORS environment variable.
Because it's a model and thus there's no GUI interaction there.
I didn't get that answer. Could you explain it a little more, please?
it's again described in the article you linked in your post. Use the QT_FILE_SELECTORS environment variable.
It says: During development you can set the environment variable QT_FILE_SELECTORS to android to simulate this. But where is that QT_FILE_SELECTORS to set it to android!?
-
It's an environment variable. You have to set it.
You can do it in Qt Creator in the Run part of the Project panel.