Results 1 to 3 of 3

Thread: Event problem on Dynamically created combo box in tablewidget

  1. #1
    Join Date
    Jun 2015
    Posts
    3
    Qt products
    Platforms
    Unix/X11

    Default Event problem on Dynamically created combo box in tablewidget

    Hi,

    I have a QTableWidget, in which I create dynamically some QComboBox. I simplified the code so things might be missing but the important part is in there, it looks like this :

    Qt Code:
    1. def testPrint(self, index):
    2.  
    3. print index
    4.  
    5.  
    6. def itemComboBox(self, array, curIndex):
    7.  
    8. comboBox = QtGui.QComboBox(self)
    9. comboBox.addItems(array)
    10. comboBox.setCurrentIndex(curIndex)
    11.  
    12. return comboBox
    13.  
    14.  
    15. def createTable(self):
    16.  
    17. tw = self.ui.tableWidget
    18.  
    19. version = [ 'v01', 'v02', 'v03' ]
    20.  
    21. cb = []
    22. for i range(0,len(version)):
    23.  
    24. cb.append(self.itemComboBox(version,'v01'))
    25. tw.setCellWidget(i, 0, cb[i])
    To copy to clipboard, switch view to plain text mode 

    So no problem with that, it creates what I need to see and when I go through each rows I get the values I want. However, I'm trying to run a function when the comboBox value get changed. I first tried that :

    Qt Code:
    1. def createTable(self):
    2.  
    3. tw = self.ui.tableWidget
    4.  
    5. version = [ 'v01', 'v02', 'v03' ]
    6.  
    7. cb = []
    8. for i range(0,len(version)):
    9.  
    10. cb.append(self.itemComboBox(version,'v01'))
    11. cb[i].currentIndexChanged.connect( lambda: self.testPrint(i) ) ###LINE###
    12. tw.setCellWidget(i, 0, cb[i])
    To copy to clipboard, switch view to plain text mode 

    But with this, for some reason, each combobox returns the value from the last in the list, seems like I keep overriding the event in the loop but I don't see how since I use a list with index. So as a test I quickly tried something simple outside of the loop after getting rid of the line ###LINE###

    Qt Code:
    1. for k in range(0,len(version)) :
    2. cb[k].currentIndexChanged.connect( lambda: self.testPrint(k) )
    To copy to clipboard, switch view to plain text mode 

    Which still doesn't work, then because I was really suspicious I tried that instead:

    Qt Code:
    1. cb[0].currentIndexChanged.connect( lambda: self.testPrint(0) )
    2. cb[1].currentIndexChanged.connect( lambda: self.testPrint(1) )
    3. cb[2].currentIndexChanged.connect( lambda: self.testPrint(2) )
    To copy to clipboard, switch view to plain text mode 

    And that works ! I really don't get why going through a loop would not work the same way.

    Anyone can save me on this one ?

    Cheers
    Chris

  2. #2
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Event problem on Dynamically created combo box in tablewidget

    This problem is not related to Qt, but to the way Python captures variables in a closure. Your lambda refers to the variable i defined in the enclosing loop, and Python's semantics bind it to the variable's name and scope, not to its value at the time the closure is created. In other words, i is evaluated when the lambda is executed, not when it is constructed, therefore all lambdas see the last value of i.

    I found a Stack Overflow discussion with possible solutions:
    http://stackoverflow.com/questions/2...ture-in-python

    By contrast, C++ lets you choose how variables are captured, just like ordinary function parameters (by value or reference).

  3. #3
    Join Date
    Jun 2015
    Posts
    3
    Qt products
    Platforms
    Unix/X11

    Default Re: Event problem on Dynamically created combo box in tablewidget

    Thanks !

    Reading this made me understood the issue and I actually sorted it out pretty simply :

    Qt Code:
    1. def testPrint(self, index):
    2.  
    3. print index
    4.  
    5.  
    6. def itemComboBox(self, array, curIndex, ID):
    7.  
    8. comboBox = QtGui.QComboBox(self)
    9. comboBox.addItems(array)
    10. comboBox.setCurrentIndex(curIndex)
    11. comboBox.currentIndexChanged.connect( lambda: self.testPrint(ID) )
    12.  
    13. return comboBox
    14.  
    15.  
    16. def createTable(self):
    17.  
    18. tw = self.ui.tableWidget
    19.  
    20. version = [ 'v01', 'v02', 'v03' ]
    21.  
    22. for i range(0,len(version)):
    23.  
    24. cb = self.itemComboBox(version,'v01',i)
    25. tw.setCellWidget(i, 0, cb)
    To copy to clipboard, switch view to plain text mode 

    By passing the i variable when creating the combo box and creating the event in itemComboBox function itself it sorts out the problem.

    Thanks again

    Chris

Similar Threads

  1. Dynamically created buttons to one slot
    By rdkk in forum Qt Programming
    Replies: 11
    Last Post: 5th June 2013, 23:33
  2. Dynamically created buttons.
    By Tomasz in forum Newbie
    Replies: 26
    Last Post: 2nd December 2010, 09:40
  3. Replies: 7
    Last Post: 2nd August 2010, 12:28
  4. multiple key combo event
    By tikay in forum Qt Programming
    Replies: 2
    Last Post: 28th June 2010, 15:26
  5. tableWidget created in Qt Creator not updated
    By binaural in forum Qt Programming
    Replies: 2
    Last Post: 10th July 2009, 21:50

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.