How to create a message dialog using QML Control elements(such as combobox, textfield, checkbox..)

User picture User · Jul 27, 2014 · Viewed 16.4k times · Source

I want to create a message dialog in the following way

For example:My combobox has 2 name, “chkbx”(symbolic name for the checkbox), “txtedt”(symbolic name for the text field).

Whenever i select chkbox or txtedt from combobox drop down list, then my combo box should connect me to actual checkbox and textedit element respectively.

I have a “show dialog” button on status bar when i press that button it should popup selected option(checkbox or line edit)

Please suggest me how can i do it.

EDIT Here is the code and the problem i am facing with combobox options is, neither i am not able to get icons in my message dialog nor i dont know how i can see checkbox or line edit in message dialog, i am a beginner and struggling to explore the tricky ways used in QML..

import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.1
import QtQuick.Window 2.0


Item {
    id: root
    width: 580
    height: 400
    SystemPalette { id: palette }
    clip: true

    //! [messagedialog]
    MessageDialog {
        id: messageDialog
        visible: messageDialogVisible.checked
        modality: messageDialogModal.checked ? Qt.WindowModal : Qt.NonModal
        title: windowTitleField.text
        text: customizeText.checked ? textField.text : ""
        informativeText: customizeInformativeText.checked ? informativeTextField.text : ""
        onButtonClicked: console.log("clicked button " + clickedButton)
        onAccepted: lastChosen.text = "Accepted " +
            (clickedButton == StandardButton.Ok ? "(OK)" : (clickedButton == StandardButton.Retry ? "(Retry)" : "(Ignore)"))
        onRejected: lastChosen.text = "Rejected " +
            (clickedButton == StandardButton.Close ? "(Close)" : (clickedButton == StandardButton.Abort ? "(Abort)" : "(Cancel)"))
        onHelp: lastChosen.text = "Yelped for help!"
        onYes: lastChosen.text = (clickedButton == StandardButton.Yes ? "Yeessss!!" : "Yes, now and always")
        onNo: lastChosen.text = (clickedButton == StandardButton.No ? "Oh No." : "No, no")

    }
    //! [messagedialog]

    Column {
        anchors.fill: parent
        anchors.margins: 12
        spacing: 8
        Text {
            color: palette.windowText
            font.bold: true
            text: "Message dialog properties:"
        }
        CheckBox {
            id: messageDialogModal
            text: "Modal"
            checked: true
            Binding on checked { value: messageDialog.modality != Qt.NonModal }
        }
        CheckBox {
            id: customizeTitle
            text: "Window Title"
            checked: true
            width: parent.width
            TextField {
                id: windowTitleField
                anchors.right: parent.right
               width: informativeTextField.width
                text: "Alert"
            }
        }

        Row {

            Text {
                text: "Combo box items and icon selection:"
            }
            spacing: 8

            function createIcon(str) {
                switch(str) {

                     case Critical:
                    messageDialog.icon = StandardIcon.Critical
                     console.log("Critical")
                      break;
                      case Question:
                     messageDialog.icon = StandardIcon.Question
                          break;
                        case  checkbox:
                            //how to add checkbox here in order to show it in my message dialog ?
                            break;
                      case  textedit:
                          //how to add textedit here in order to show it in message dialog ?
                            break;
                      default:
                          break
                      }
                  }

           ComboBox {
                id : cbox
                editable: true
                currentIndex: 0
                model: ListModel {
                    id: cbItems
                    ListElement { text: "Critical"}
                    ListElement { text: "Question"}
                    ListElement { text: "checkbox"}
                    ListElement { text: "textedit"}
                }
               onCurrentIndexChanged: console.debug(cbItems.get(currentIndex).text)

               onAccepted: parent.createIcon(cbItems.get(currentIndex).text)
                 }
                }
         CheckBox {
            id: customizeText
            text: "Primary Text"
            checked: true
            width: parent.width
            TextField {
                id: textField
                anchors.right: parent.right
                width: informativeTextField.width
                text: "Attention Please"
            }
        }

        CheckBox {
            id: customizeInformativeText
            text: "Informative Text"
            checked: true
            width: parent.width
            TextField {
                id: informativeTextField
                anchors.right: parent.right
                width: root.width - customizeInformativeText.implicitWidth - 20
                text: "Be alert!"
            }
        }
        Text {
            text: "Buttons:"
        }
        Flow {
            spacing: 8
            width: parent.width
            property bool updating: false
            function updateButtons(button, checked) {
                if (updating) return
                updating = true
                var buttons = 0
                for (var i = 0; i < children.length; ++i)
                    if (children[i].checked)
                        buttons |= children[i].button
                if (!buttons)
                    buttons = StandardButton.Ok
                messageDialog.standardButtons = buttons
                updating = false
            }

            CheckBox {
                text: "Help"
                property int button: StandardButton.Help
                onCheckedChanged: parent.updateButtons(button, checked)
            }


            CheckBox {
                text: "Close"
                property int button: StandardButton.Close
                onCheckedChanged: parent.updateButtons(button, checked)
            }

            CheckBox {
                text: "Cancel"
                property int button: StandardButton.Cancel
                onCheckedChanged: parent.updateButtons(button, checked)
            }


        }


    }

    Rectangle {
        anchors {
            left: parent.left
            right: parent.right
            bottom: parent.bottom
        }
        height: buttonRow.height * 1.2
        color: Qt.darker(palette.window, 1.1)
        border.color: Qt.darker(palette.window, 1.3)
        Row {
            id: buttonRow
            spacing: 6
            anchors.verticalCenter: parent.verticalCenter
            anchors.left: parent.left
            anchors.leftMargin: 12
            width: parent.width
            Button {
                text: "Show Dialog"
                anchors.verticalCenter: parent.verticalCenter
                onClicked: messageDialog.open()
            }
            Button {
                text: "Close"
                anchors.verticalCenter: parent.verticalCenter
                onClicked: messageDialog.close()
            }
        }

            }
        }

Answer

folibis picture folibis · Jul 28, 2014

I still can't understand what are you going to do. Assume, you want some custom dialog with varying content. First of all, I guess MessageDialog is not good idea just because you cannot define custom controls inside it. But you can create a custom one.

Simple example:

Popup.qml

import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0  

Window {
    id: mypopDialog
    title: "MyPopup"
    width: 300
    height: 100
    flags: Qt.Dialog
    modality: Qt.WindowModal
    property int popupType: 1
    property string returnValue: ""

    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 10

        RowLayout {
            Layout.fillWidth: true
            Layout.fillHeight: true
            spacing: 20
            Image {
                source: popupType == 1 ? "combo.png" : "edittext.png"
            }
            Loader {
                id: loader
                Layout.alignment: Qt.AlignRight
                Layout.fillWidth: true
                sourceComponent: popupType == 1 ? comboboxComponent : editboxComponent
                property string myvalue : popupType == 1 ? item.currentText : item.text
                Component {
                    id: comboboxComponent

                    ComboBox {
                        id: comboBox

                        model: ListModel {
                            ListElement { text: "Banana" }
                            ListElement { text: "Apple" }
                            ListElement { text: "Coconut" }
                        }
                    }
                }
                Component {
                    id: editboxComponent
                    TextEdit {
                        id: textEdit
                    }
                }
            }
        }

        Rectangle {
            height: 30
            Layout.fillWidth: true
            Button {
                text: "Ok"
                anchors.centerIn: parent
                onClicked: {
                    returnValue = loader.myvalue;
                    mypopDialog.close();
                }
            }
        }
    }
}

Here I use Loader to load appropriate content according to popupType property (1 - combobox, 2 - textedit)

So now you can use this file in any place where you want.

import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0

Button {
    text: "Test dialog"
    onClicked: {
        var component = Qt.createComponent("Popup.qml");
        if (component.status === Component.Ready) {
        var dialog = component.createObject(parent,{popupType: 1});
        dialogConnection.target = dialog
        dialog.show();
   }
}

Connections {
    id: dialogConnection
    onVisibleChanged: {
        if(!target.visible)
            console.log(target.returnValue);       
    }
}

Here I use Connections to get back some result from the dialog. If you don't need it just remove the Connections item