user1976336
user1976336

Reputation: 217

PySide One slot to multiple widgets

I am creating a small app in python using PySide. I read lines from a text file and display each line in a separate QLineEdit Widget. Each "entry" has 2 line edits and 2 QPushButtons. For every line I add those widgets. My problem is that I set a signal-slot for the QPushButtons, but when all the "entries" are generated, only the last entries QPushButtons connects to the slot. May someone please help me.

Here is my code

class ItemLogger(QtGui.QMainWindow, Ui.Ui_MainWindow):
def __init__(self, parent = None):
    super(ItemLogger, self).__init__(parent)
    self.setupUi(self)

    self.parseBossItem()
    self.comboBox.currentIndexChanged.connect(self.parseBossItem)
    self.increase.clicked.connect(self.add_subtract)


def add_subtract(self):
    initial = 1
    print "kajskasdjflsdkjflk"

def addRow(self, item):
    self.frame  = QtGui.QFrame()
    self.layout = QtGui.QHBoxLayout()

    self.itemName   = QtGui.QLineEdit(item)
    self.itemName.setReadOnly(True)

    self.itemCount  = QtGui.QLineEdit()
    self.itemCount.setText("0")
    self.itemCount.setMaximumWidth(40)

    self.decrease   = QtGui.QPushButton("-")
    self.increase   = QtGui.QPushButton("+")

    self.layout.addWidget(self.itemName)
    self.layout.addWidget(self.itemCount)
    self.layout.addWidget(self.decrease)
    self.layout.addWidget(self.increase)

    self.frame.setLayout(self.layout)

    self.verticalLayout_3.addWidget(self.frame)



def parseBossItem(self):
    if self.comboBox.currentText() == "Item_1":
        item_list = open("BossItems/Random_Item")
        for line in item_list.readlines():
            self.addRow(line)

    if self.comboBox.currentText() == "Item_2":
        item_list = open("BossItems/Random_Item_2")
        for line in item_list.readlines():
            self.addRow(line)

Upvotes: 0

Views: 1198

Answers (1)

Charles Brunet
Charles Brunet

Reputation: 23160

This is because you only connected the last entry.

Here is what you are actually doing:

  1. You add row for item 1, and assign button widgets to self.decrease, self.increase.
  2. You add row for item 2, replacing values of self.decrease, self.increase by newly created widgets.
  3. You connect self.increase, which is now the last added widget.

If you don't need access to you widgets after their creation, you should consider using local variables (e.g. without self) and connecting the signal inside the addRow function.

If you need to keep track of widget references, then you could add them to an array:

# Somewhere in __init__ or in parseBossItem
self.increase = []

# in addRow
self.increase.append(QtGui.QPushButton("+"))
self.layout.addWidget(self.increase[-1])
self.increase[-1].clicked.connect(self.add_subtract)
# and so on...

To use the same slot form different senders, you need to identify who sent the signal. You could do something like this:

def onIncrease(self):
    button = self.sender()
    if isinstance(button, QtGui.QPushButton):
        buttonName = button.text()
        if buttonName == 'name of button 1':
            self.itemCount[0].setText(str(int(self.itemCount[0])+1))
        elif buttonName == 'name of button 2':
            ...

Off course, this is assuming you put each QLineEdit in the array self.itemCount.


Since all your buttons have the same name, we need to use another approach.

# in addRow
self.increase.clicked.connect(lambda: self.onIncrease(itemCount))

def onIncrease(self, edit):
    edit.setText(str(int(edit.text()+1))

Upvotes: 1

Related Questions