Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
5.11.0, 5.11.1
-
None
Description
I'm about 3 workarounds deep in this, so trying to make a minimal example is difficult, if time permits I'll try to supply that next week.
The base Problem:
I have a list of strings, in this case Names. Each name needs to be Toggleable; which is currently achieved with a ListView using CheckDelegates.
ListView { id: doclistView anchors.fill: parent model: Doctors ScrollBar.vertical: ScrollBar { policy: doclistView.contentHeight > doclistView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff } interactive: doclistView.contentHeight > doclistView.height clip: true delegate: CheckDelegate { height: 24 padding: 0 LayoutMirroring.enabled: true text: modelData onCheckStateChanged: HP.toggledocuser(userlistView.currentIndex, index, checked) } }
(direct copy, so a lot of irrelevant stuff in there.)
Now, toggledocuser sends the correct currentIndex to python space, that part works fine.
However, this state gets saved and needs to later be restored from python space to QML
And that is the part I've tried on several ways:
- Custom QAbstractListModel
Problem: roleNames() expectes a QHash back, No idea how to emit one with python. This certainly did not work:
def roleNames(self):
return Qt.DisplayRole | Qt.EditRole | Qt.UserRole
2. using CurrentItem
QML sends a request for loaded States, calling this method:
@Slot(QObject, str) def requestAllowedDocs(self, window, username): print("Requesting for {}".format(username)) window.resetdoctors() for i, doctor in enumerate(self.doctorlist): if self.reverse_lookup[doctor] in self.userconfig[username]["allowed_doctors"]: print("Setting", i) window.setdoctor(i)
Calling this in QML Space:
function resetdoctors() { for (var delegate in doclistView.contentItem.children) { doclistView.contentItem.children[delegate].checked = false; } } function setdoctor(index) { doclistView.currentIndex = index; doclistView.currentItem.checked = true; HP.log(doclistView.currentIndex+" "+doclistView.currentItem.checked); }
However, there are some skips;
Here the log:
Requesting for Neuer Benutzer Setting 0 0 true Setting 1 1 true Setting 2 2 true Setting 3 3 true
Which would seem to indicate 0 through 3 would be set to true.
Well, not so much.
3. Pretty much the same as 2, but using indexes directly without ever setting currentIndex of the ListView, however it fails even weirder:
function setdoctor(index) { doclistView.contentItem.children[index].checked = true; //this is line 23 HP.log(index+" "+doclistView.contentItem.children[index].checked); }
default:<Unknown File>:23: TypeError: Type error Requesting for Neuer Benutzer default:<Unknown File>:23: TypeError: Type error Setting 0 0 true Setting 1 1 true Setting 2 Setting 3
At this point I'm out of ideas how to get this to work at all.
Edit: I do know a workaround now;
Load the QML in with Jinja and template in proper checkboxes with IDs and address them individually from QML, with a manager from Python. But that seems like a lot of work for something that should just work.
Edit2:
Thinking this might be some kind of racing condition, this actually fixed it (Timer is added):
Timer { interval: 100 running: true onTriggered: userchange() } function resetdoctors() { for (var delegate in doclistView.contentItem.children) { doclistView.contentItem.children[delegate].checked = false; } } function setdoctor(index) { doclistView.currentIndex = index; doclistView.currentItem.checked = true; HP.log(doclistView.currentIndex+" "+doclistView.currentItem.checked); } function userchange() { var username = userlistView.model.data(userlistView.model.index(userlistView.currentIndex, 0)); if (username === undefined){ docfilter.enabled = false exportbutton.enabled = false rightpane.enabled = false removeuserbutton.enabled = false } else { removeuserbutton.enabled = true docfilter.enabled = true rightpane.enabled = true exportbutton.enabled = true buttonnamesubmit.visible = false; buttonpasssubmit.visible = false; nametext.text = username; passtext.text = ""; HP.requestUserData(appwindow, username); HP.requestAllowedDocs(appwindow, username); } }
I don't know why it works 100 milliseconds later, but it does.