0

In the example below I am trying to use the selection's of two separate comboboxes as two arguments of a function. If 3 and 4 are selected an output of 12 should be produced and so on. How do I write this to send the first combo selection as the first argument and the second combo selection as the second argument?

At the moment, both of the connections return a 'multiply() takes exactly 2 arguments (1 given)" error because the two comboboxes are not simultaneously but separately connected to the function.

from PyQt4 import QtCore, QtGui

class Ui_MainWindow(QtGui.QMainWindow):

    def setupUi(self):

        window = QtGui.QMainWindow(self)
        window.table = QtGui.QTableWidget()
        window.table.setRowCount(2)
        window.table.setColumnCount(1)
        window.setCentralWidget(window.table)

        def multiply(x, y):
            return x * y

        combo_x = QtGui.QComboBox()
        combo_y = QtGui.QComboBox()
        for i in range(1, 10):
            combo_x.addItem(str(i))
            combo_y.addItem(str(i))

        combo_x.activated[int].connect(multiply)
        combo_y.activated[int].connect(multiply)

        window.table.setCellWidget(0, 0, combo_x)
        window.table.setCellWidget(1, 0, combo_y)

        desired = []
        for x in range(1, 10):
            for y in range(1, 10):
                desired.append(multiply(x, y))

        window.show()

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    ui = Ui_MainWindow()
    ui.setupUi()
    sys.exit(app.exec_())

2 Answers 2

1

The problem that you face is that you don't get the values to multiply both from the same event.

The solution is to use a function which gets called on every change and which agregates the values to process from the two (or more) items in the table. So instead of "sending" the values, the function you call "pulls" them from that table. To this end the table needs of course be visible from outside the function, which can be done by making it a class attribute.

from PyQt4 import QtGui

class Ui_MainWindow(QtGui.QMainWindow):

    def setupUi(self):
        self.table = QtGui.QTableWidget()
        self.table.setRowCount(3)
        self.table.setColumnCount(1)
        self.setCentralWidget(self.table)

        combo_x = QtGui.QComboBox()
        combo_y = QtGui.QComboBox()
        for i in range(1, 10):
            combo_x.addItem(str(i))
            combo_y.addItem(str(i ** 2))

        combo_x.activated.connect(self.update)
        combo_y.activated.connect(self.update)

        self.table.setCellWidget(0, 0, combo_x)
        self.table.setCellWidget(1, 0, combo_y)
        self.table.setCellWidget(2,0,QtGui.QLabel(""))

        self.show()

    def multiply(self,x,y):
        return x*y

    def update(self):
        x = self.table.cellWidget(0, 0).currentText() #row, col
        y = self.table.cellWidget(1, 0).currentText()
        result = self.multiply(int(x), int(y))
        self.table.cellWidget(2, 0).setText(str(result))

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    ui = Ui_MainWindow()
    ui.setupUi()
    sys.exit(app.exec_())
Sign up to request clarification or add additional context in comments.

Comments

1

So, first of all, I would recommend not defining functions inside setupUI and make the widgets that you want to make use children/attributes of the QMainWindow. Then you could access them in your multiply method. For your answer in particular, I would do the following:

class Ui_MainWindow(QtGui.QMainWindow):

    def setupUi(self):

        # No Changes made here
        window = QtGui.QMainWindow(self)
        window.table = QtGui.QTableWidget()
        window.table.setRowCount(2)
        window.table.setColumnCount(1)
        window.setCentralWidget(window.table)

        # Make attribute of MainWindow
        self.combo_x = QtGui.QComboBox()
        self.combo_y = QtGui.QComboBox()
        for i in range(1, 10):
            self.combo_x.addItem(str(i))
            self.combo_y.addItem(str(i))

        self.combo_x.activated[int].connect(self.multiply)
        self.combo_y.activated[int].connect(self.multiply)

        window.table.setCellWidget(0, 0, self.combo_x)
        window.table.setCellWidget(1, 0, self.combo_y)

        window.show()

    def multiply(self):

        # Grab Index of comboboxes
        x = int(self.combo_x.currentIndex())+1
        y = int(self.combo_y.currentIndex())+1

        # Multiply
        print x * y

Hope this is what you are looking for.

4 Comments

This nearly works with the edit suggested but selecting n in either combobox results in (n - 1) being used for the calculation (i.e "1 x 1" = 0, "2 x 2" = 1, "3 x 3" = 4). I tried to fix it by setting x and y equal to int(self.combo_x or y.currentIndex() + 1) but this made odd things happen.
Thats because indices in python start from 0. I fixed it in the code.
This does work but it seems to be more of a workaround. It doesn't actually use the content of the comboBox through the function. In this context it suffices but in my real context the selection is text so the currentIndex is not what should be used.
Sorry, I thought you wanted the index. To get the "content", or text, you can then use int(self.combo_x.currentText())

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.