Search code examples
comboboxqmlqt5qt-quickmessagedialog

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


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()
            }
        }

            }
        }

Solution

  • 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