PDA

View Full Version : PYQT4 QlistWidget : currentItem and selectedItem different



alkimia
3rd January 2017, 22:10
Hi Everyone,

So I curious to know how does the currentItem()) and selectedItems() methods of the QlistWidget actually work.

What I have(simplified):
-I have a QlistWidget with a list of items(usersList)
-I have QAbstractViewItem.extendedSelection activated
-I have QLineEdit(userAge)
-I have a dictionary DataDict with key:value ==> ListItem.text():QlineEdit.text())

-I have connected the userAge.textChanged to the function saveData


def saveData():

currentItem=str(usersList.currentItem().text())

DataDict[currentItem]=QlineEdit.text()


-I have connected usersList.currentItemChanged to the function loadData:


def loadData(current,_previous):

currentItem=current.text()
#get data
data=dataDict[currentItem]
#clear previous data
userAge.clear()
#set Data
userAge.setText(data)


what I want to do/problem(simplified):

-right now the saving/loading of the data in the UI works for one item
(currentitem) but I want the user to be able to select multiple Items
change the usersAge and setData to all the selectedItems , and I'm trying to do this by modifying my saveData() like so:


def saveData():

for item in usersList.selectedItems():
currentItem=str(item.text())
DataDict[currentItem]=QlineEdit.text()

-the problem now is that when I changed currentItem by clicking on another one item the data of the previous gets overwritten by the current loaded one

-I know whats probably happening is (if i'm not wrong):
1.I click in another item(changing current Item)
2.currentItemChanged is triggered
3.loadData() is called
3.a userAge.clear() is called
3.b userAge.textChanged is triggered
3.c saveData() is called (now with empty)
3.d userAge.setText(data)
3.e userAge.textChanged is triggered
3.f saveData() is called(with the loaded data)

-In my head it should work fine because currentItem/selectedItem are the same, but what is causing the problem is that when saveData() is called , the currentItem and the selectedItem are different, if I print currentItem.text() and selectedItems()[0].text() when I entered savData()

I noticed that currentItem= currentItem (which is correct) but selectedItems()[0].text() = previousItem (which is wrong cause only the currentItem is selected)

why is this happening? what am I doing wrong? or what am I missing?
why is the selection not getting updated when you changed current Item?

I a newbie so I might be doing something wrong , but if not could someone please help me understand what is happening?

thank you very much in advance

Hi
so after playing around and trying some different stuff (not logical just trying) I found a solution to this problem , so what I have to do is called the usersList.setCurrentItem(current) inside the loadData() function like so:


def loadData(current,_previous):

currentItem=current.text()
#get data
data=dataDict[currentItem]
#clear previous data
userAge.clear()
#FIX
usersList.setCurrentItem(current)
#set Data
userAge.setText(data)

this seems very redundant to me , but by doing this, when I print currentItem and selectedItems()[0] (when only one item selected) in saveData() it prints currentItem==selectedItems()[0] , so the onlye data getting overwritten is the currentItem,selectedItems()[0] which is own data which give me the behaviour I want

but I'm still clueless why this happens and why this fixes the issue

cheers

anda_skoa
4th January 2017, 14:32
You also don't necessarily have to call "clear()" on userAge, "setText()" will overwrite the value anyway.

Also, one technique that is sometimes useful to handle change by user and change by program differently is to disable signals when changing a component programatically.

E.g.


def loadData(current)
# ....
userAge.blockSignals(true)
userAge.setText(current)
userAge.blockSignals(false)

Here setText() will not result in textChanged() as signals had been blocked, so loadData() does not trigger saveData()

Cheers,
_