Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    QML ListView and QSqlTableModel

    QML and Qt Quick
    1
    3
    4080
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • L
      Lucijan last edited by

      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;
          }
      }
      

      }
      @

      1 Reply Last reply Reply Quote 0
      • L
        Lucijan last edited by

        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?

        1 Reply Last reply Reply Quote 0
        • L
          Lucijan last edited by

          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

          1 Reply Last reply Reply Quote 0
          • First post
            Last post