How do I change a ComboBox model and remember the previous selection?
Solved
QML and Qt Quick
-
Hi All,
I have a few combo boxes that represent the date. I want to change the number of days in the combo box when the month changes but it must remember the previous selection. The problem is that the first time I change the month, the day always jumps to 1. It works properly after that first change.
This is what I have:
/** * main.qml * Copyright (c) 2021 Hive Inc. */ import QtQuick import QtQuick.Controls.Material import QtQuick.Layouts import 'yocto' as Yocto ApplicationWindow { property date now: new Date() width: 800 height: 600 title: 'Hive Socials' visible: true Material.accent: Material.Amber /** * Return the number of days in the month. */ function days() { let months30 = ['April', 'June', 'September', 'November']; if (comboMonth.currentText == 'February') { return _bridge.days_feb(comboYear.currentText); } else if (months30.includes(comboMonth.currentText)) { return _bridge.days_30(); } return _bridge.days(); } /** * Enable the Post button if: * 1. An account is selected. * 2. There is something to post. * 3. The date and time is in the future. */ function enablePost() { let when = new Date( comboYear.currentText, comboMonth.currentIndex, comboDay.currentText, comboHour.currentIndex, comboMinute.currentIndex); return (comboAccounts.currentText != '' && textPost.text != '' && when > new Date()); } function showDialog(dialog) { loader.source = dialog; loader.item.open(); } /** * Update the number of days when the month changes. * Keep the current selection if it's still valid. */ function updateDays() { let day = comboDay.currentIndex; console.log(day); let numDays = days(); comboDay.model = numDays; if (day < numDays.length) { comboDay.currentIndex = day; } } /** * Return the current year and the next year. */ function years() { let year = now.getFullYear(); return [year, year + 1]; } header: ToolBar { Material.background: Material.Amber RowLayout { anchors.fill: parent ToolButton { id: buttonMenu icon.source: 'qrc:/images/menu.png' Layout.alignment: Qt.AlignRight onClicked: menu.open() Menu { id: menu y: buttonMenu.height MenuItem { text: 'Accounts' onClicked: showDialog('Accounts.qml') } MenuItem { text: 'About Hive Socials' onClicked: showDialog('About.qml') } } } } } ColumnLayout { anchors.fill: parent ColumnLayout { Layout.margins: 18 spacing: 12 // Name of account RowLayout { spacing: 12 Label {text: 'Account:'} ComboBox { id: comboAccounts textRole: 'display' model: _bridge.account_names() } } // Create post ColumnLayout { TextArea { id: textPost placeholderText: 'Create post' Layout.fillWidth: true Layout.fillHeight: true } Button {text: 'Photo/Video…'} } // Date and time RowLayout { spacing: 24 // Date RowLayout { ComboBox { id: comboDay model: days() currentIndex: now.getDate() - 1 // The index starts at 0. Layout.preferredWidth: 68 } ComboBox { id: comboMonth model: _bridge.months() currentIndex: now.getMonth() onActivated: (index) => updateDays() } ComboBox { id: comboYear model: years() Layout.preferredWidth: 80 } } // Time RowLayout { ComboBox { id: comboHour model: _bridge.hours() currentIndex: now.getHours() editable: true Layout.preferredWidth: 68 } Label {text: ':'} ComboBox { id: comboMinute model: _bridge.minutes() currentIndex: now.getMinutes() editable: true Layout.preferredWidth: 68 } } Item {Layout.fillWidth: true} Yocto.Button { id: buttonPost text: '<b>Post</b>' enabled: false Material.background: Material.Blue Material.foreground: 'white' states: State { when: enablePost() PropertyChanges { target: buttonPost enabled: true } } } } } } Loader { id: loader anchors.centerIn: parent } }
-
I'm such an idiot, lol. I got it working properly with:
/** * Update the number of days when the month changes. * Keep the current selection if it's still valid. */ function updateDays(index) { let numDays = days(); comboDay.model = numDays; if (index < numDays.length) { comboDay.currentIndex = index; } } ... ComboBox { id: comboMonth model: _bridge.months() currentIndex: now.getMonth() onActivated: (index) => updateDays(index) }