0
votes

In my Qt Quick(Qt v5.4 and QtQuick 2.4) project I have these five .qml files:

  1. MainForm.ui.qml - Which contains the main window of the application
  2. main.qml - Contains all the functionality implementations of objects of mainForm.ui.qml, such as onClicked events, calling c++ functions getting value from textInputs etc.

Q: Is my current setup for implementing functionality correct? Or should I implement all these things in the same file??

  1. dialog1.qml - Contains some text inputs for some settings etc.
  2. dialog2.qml - For some lists and tables in my application.
  3. dialog3.qml - Also contains some objects for an c++ function.

All these qml files are created and destroyed at different times, on different button clicks. I'm using this method to open a dialog

`addMenuArea.onClicked: {
Qt.createComponent("addMenuAppDialog.qml").createObject(rootWindow, {});
}`

and for destroying the dialog:

MouseArea{
    anchors.fill: parent
    onClicked: {
        dialogComponent.destroy()
    }
}

Now currently these dialogs doesn't have any functionality, like the main window, I want to do implement it all in one file(main.qml) without any javascript if possible. I have no Idea on how to link all the dialogs and main.qml so I can add the functions in main.qml. Any help will be great!

2
Which qt and which qt-quick? Version info missing.user1095108
@user1095108 Edited the question, take a look!Amol Borkar
This is one possible way. Another way would be to use Loader and change out the source file name. This would handle the creation/destruction of the objects. The third way would be to instantiate all the dialog and hide all of them except for the one that should be visible, but this uses more memory than needed.saiarcot895
@saiarcot895 I'm searching the docs for this. Is there some method or function in Loader which will link the dialogs and main.qml??Amol Borkar
@EdwardMckinzie: Loader.item contains a reference to the top-level object that gets loaded. You can use that in conjunction with Loader.source.saiarcot895

2 Answers

1
votes

Assume that you have a SimpleDialog.qml file:

Window { //or Item, Rectangle, ... whatever
    signal userPressedSomething()
    property string userNameString
    function textEditText(){ /*return textEdit.text()*/ }
    //...
}

And assume that your main.qml has the following functions which try to handle the necessary program logic:

  1. openSimpleDialog() to load the SimpleDialog
  2. closeSimpleDialog() to close the SimpleDialog
  3. userPressedSomethingInSimpleDialog()
  4. getSimpleDialogInfo()

You can use Loader to load, unload, obtain data from the dialog, and use Connections to catch signals. Here is a simple example in main.qml:

Loader { id: simpleDialogLoader }

function openSimpleDialog() { simpleDialogLoader.source = "SimpleDialog.qml"; }

function closeSimpleDialog() { simpleDialogLoader.source = ""; }

function getSimpleDialogInfo() {
    if (simpleDialogLoader.source !== "SimpleDialog.qml") { return; }
    console.log(simpleDialogLoader.item.userNameString); //property
    console.log(simpleDialogLoader.item.textEditText()); //function
}

Connections {
    target: simpleDialogLoader //to Loader
    onUserPressedSomething: { userPressedSomethingInSimpleDialog(); }
}

Let's explain the detail:

  • Use Loader.source property to dynamically load/unload SimpleDialog in the openSimpleDialog and closeSimpleDialog functions.
  • Loader.item holds the object created by the loader, and this is all the getSimpleDialogInfo needs.
  • Signals from SimpleDialog can be caught by set the Connections.target to Loader.item.
1
votes

Though you can define all the dialogs and main window in main.qml file, I strongly discourage this approach. As your dialogs and your main window grow in complexity (they definitely will become more complex), your QML code will become harder and harder to understand.

Doing

Qt.createComponent("addMenuAppDialog.qml").createObject(rootWindow, {})

involves loading QML file from HDD so I don't recommend calling it on every mouse click. I suggest 2 alternatives to that approach.

Alternative 1

Create a component for each dialog inside your main window:

Component {
    id: dialog1Component
    Dialog1 {}
}

Then you'll be able to create it by calling dialog1Component.createObject(rootWindow, {}), and you'll still need to destroy it manually when it closes.

Alternative 2

This is approach that is used in my app to present dialogs.

Create dialog declaratively (place it inside your main window):

MainWindow {
    Dialog1 {
        id: dialog1
    }
}

Then you'll be able to show it by calling dialog1.open() and to hide it by calling dialog1.close().