Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QML ListView and QSqlTableModel
Forum Update on Monday, May 27th 2025

QML ListView and QSqlTableModel

Scheduled Pinned Locked Moved QML and Qt Quick
3 Posts 1 Posters 4.3k Views
  • 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 Offline
    L Offline
    Lucijan
    wrote on 26 May 2013, 11:52 last edited by
    #1

    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
    0
    • L Offline
      L Offline
      Lucijan
      wrote on 26 May 2013, 11:53 last edited by
      #2

      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
      0
      • L Offline
        L Offline
        Lucijan
        wrote on 31 May 2013, 15:44 last edited by
        #3

        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
        0

        1/3

        26 May 2013, 11:52

        • Login

        • Login or register to search.
        1 out of 3
        • First post
          1/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved