QML ListView and QSqlTableModel



  • Post 1/2 (exceeds the 6000 character limit)

    Hello,

    I am still new to QML and I have a problem trying to use a QSqlDatabase and QML ListView. I've searched the forum but can't find a solution.

    The application uses QML for most of the work, but it needs to get data from an MS Access database and show it inside QML elements containing a ListView. To do this, I have made a C++ BaseModel class which inherits from QSqlTableModel. I've made a few test programs and managed to connect the database with the ListView to show the data.

    Here's the problem, though. The QML part of the application uses a Loader in the main file to load different pages. These are loaded when I click certain buttons and they hold most of the content. One of these pages needs to contain ComboBoxes which pull data from the database. To make the ComboBox I have first created a ListBox which contains a ListView and a custom-made ListItem which is the delegate. The model for the ListView comes from the C++ BaseModel class. The problem is that I don't know how to de-couple the ListBox/ComboBox from the model to be able to show different data in each ComboBox I make. Currently, it will work if I specify the name of the column directly in the delegate, but because each ComboBox uses a different column (and a different table), I need to be able to do this outside the ComboBox definition, i.e. something like:

    @
    ComboBox {
    id: topicComboBox
    //...
    model: topicModel
    delegate: Topic //this is the column name
    }

    ComboBox {
    id: keyWordComboBox
    //...
    model: keywordModel
    delegate: KeyWord //this is the column name
    }
    @

    I've tried doing this, but I get the following error:

    bq. ReferenceError: KljucnaRijec is not defined

    Do I even need different models for setting each ComboBox?

    I'll provide as much code as possible.

    ListBox.qml

    @import QtQuick 2.0

    Rectangle {
    id: listBox
    width: 400
    height: 500
    color: "#1a4381"
    border.color: "#ffffff"

    property int selectedIndex: testView.currentIndex
    property string selectedText: ""
    property variant listModel
    property string tableField
    
    signal indexChanged()
    
    Component {
        id: delegateItem
    
        ListItem {
            text: listBox.tableField ? listBox.tableField : ""
            width: parent.width
            anchors.left: parent.left
            anchors.leftMargin: 2
            onListItemClick: {
                listBox.selectedText = text;
                testView.currentIndex = index;
            }
        }
    }
    
    ListView {
        id: testView
        clip: true
        anchors.centerIn: parent
        width: parent.width - 2
        height: parent.height - 2
        model: listBox.listModel
        delegate: delegateItem
    
        currentIndex: -1
        onContentHeightChanged: {
            if (listBox.height < testView.contentHeight)
                vScrollBar.visible = true;
            else
                vScrollBar.visible = false;
        }
    
        onCurrentIndexChanged: indexChanged()
    
        ScrollBar {
            id: vScrollBar
            anchors.right: parent.right
            height: parent.height
            position: testView.visibleArea.yPosition
            pageSize: testView.visibleArea.heightRatio
    
            visible: (testView.height < testView.contentHeight) ? true : false
        }
    }
    

    }
    @

    ComboBox.qml

    @import QtQuick 2.0

    Item {
    id: comboBox
    width: 400
    height: selectedItemRect.height

    property alias imageSource: arrowImage.source
    property color itemColor: "#1a4381"
    property color borderColor: "#ffffff"
    property alias text: selectedItemText.text
    property alias listBoxHeight: comboListBox.height
    property variant model
    property string field
    
    Rectangle {
        id: selectedItemRect
        anchors.left: parent.left
        anchors.top: parent.top
        width: parent.width
        height: 20
        color: comboBox.itemColor
        border.color: comboBox.borderColor
    
        Text {
            id: selectedItemText
            color: "#ffffff"
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.left: parent.left
            anchors.leftMargin: 2
            text: ""
            font.pixelSize: 16
            font.family: "Arial"
    
        }
    
        Rectangle {
            id: arrowImageRect
            color:comboBox.itemColor
            border.color: comboBox.borderColor
            height: parent.height
            width: height //width is the same as height
            anchors.right: parent.right
            anchors.verticalCenter: parent.verticalCenter
    
            Image {
                id: arrowImage
                source: ""
                anchors.centerIn: parent
            }
        }
    
        MouseArea {
            id: comboMouseArea
            anchors.fill: parent
    
            cursorShape: Qt.PointingHandCursor
    
            onClicked: {
                if (comboListBox.visible)
                    comboListBox.visible = false;
                else
                    comboListBox.visible = true;
            }
        }
    }
    
    ListBox {
        id: comboListBox
        anchors.top: selectedItemRect.bottom
        anchors.left: selectedItemRect.left
        width: selectedItemRect.width
        height: 500
        visible: false
        listModel: comboBox.model
        tableField: comboBox.field
    
        onIndexChanged: {
            comboBox.text = selectedText;
            visible = false;
        }
    }
    

    }
    @



  • Post 2/2

    ContentsPage.qml

    @
    import QtQuick 2.0

    Item {
    id: mainContents

    Text {
        id: keywordText
        color: "#ffffff"
        anchors.verticalCenter: keywordComboBox.verticalCenter
        anchors.right: authorsIndexText.right
        wrapMode: Text.WordWrap
        text: "<b>Keyword</b>"
        font.pixelSize: 16
        font.family: "Arial"
    }
    
    ComboBox {
            id: keywordComboBox
            width: 300
            height: 20
            listBoxHeight: 570
            itemColor: "#1a4381"
            borderColor: "#ffffff"
            anchors.top: indexRect.bottom
            anchors.topMargin: 10
            anchors.left: indexRect.left
            text: "Choose a keyword --&gt;"
            imageSource: "images/DownArrow.png"
            model: keywordModel
            field: KljucnaRijec //this is the name of the column
            z: 1
    }
    

    }
    @

    The line "field: KljucnaRijec" is the one that causes the error

    bq. ReferenceError: KljucnaRijec is not defined

    main.qml

    @
    import QtQuick 2.0

    Item {
    id: mainItem
    width: 1024

    FontLoader {
        id: avantGardeBookBT
        source: "qrc:/fonts/fonts/AvantGardeBookBT.ttf"
    }
    
    Rectangle {
        id: headerRectangle
        //width: parent.width
        width: 1024
        height: 80
        color: "#1a4381"
        anchors.horizontalCenter: parent.horizontalCenter
    
        ImageTextButton {
            id: exitButton
            imageSource: "images/X.png"
            anchors.right: parent.right
            anchors.top: parent.top
            anchors.topMargin: 5
            onImageTextButtonClick: exitDialog.visible = true;
            text: "EXIT"
        }
    }
    
    Rectangle {
        id: mainRectangle
        //width: parent.width
        width: 1024
        height: mainItem.height - headerRectangle.height - 1
        color: "#1a4381"
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        Component.onCompleted: pageLoader.setSource("HomePage.qml")
    
        signal loadPage(string pageName)
    
        YesNoDialog {
            id: exitDialog
            anchors.centerIn: parent
            visible: false
            z: 1
    
            titleText: "Question"
            messageText: "Are you sure you want to quit?"
            iconSource: "images/Warning.png"
            xButtonImageSource: "images/X.png"
    
            onYesClick: Qt.quit();
            onNoClick: exitDialog.visible = false;
            onExitClick: exitDialog.visible = false;
        }
    
        Image {
            id: mainBgImage
            source: "images/Background1.png"
            anchors.fill: parent
        }
    
        Loader {
            id: pageLoader
    
            anchors.fill: parent
            //source: "HomePage.qml"
        }
    
        Connections {
            id: pageConnections
            ignoreUnknownSignals: true
            target: pageLoader.item
    
            onLoadPage: {
                if (pageName == "ContentsPage.qml")
                    keywordModel.setModel("KljucneRijeci"); //this will set data from the table specified in quotes to the model
                pageLoader.source = pageName;
    
            }
        }
    }
    

    }
    @

    I hope this is clear enough.

    Cheers,
    Lucijan

    P.S. I have a side question: if I try to use this application on Linux or Mac, will I need to install a database driver for MS Access databases or will the program call one of Qt's library files? I need to make the program work without any installation. If not, will it work if I convert the database to SQLite or some other database?



  • OK, maybe I should start with easier questions. What kind of QML type is the name of the column that I'm sending to the delegate - variant or string? Also, where is the variable visible - only in the delegate, in the file that contains the delegate and ListView or elsewhere as well? I can't make other files see it and I don't know why. This prevents me from making my ListBox a generalized component. As it stands, I would have to make three different ListBox "classes" with the only difference being the data they pull from the database. There has to be a better way to do this, but how? Could I do it from C++ and how would I go about doing that?

    Any pointers in the right direction would be really welcome.

    Cheers,
    Lucijan


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.