0

I have a PyQt GUI using Python 2.7 and QT 4.7 that opens a dialog called by a pushbutton. I can pass values between the dialog and the main GUI just fine for the most part, until it comes to a QSpinBox in the dialog box.

The class that defines the dialog is like so:

class BuyDialog(QDialog):
def __init__(self):
    QDialog.__init__(self)
    global ci, space, cash, current, price, qtyToBuy
    self.ui = Ui_buyDialog()                                            # Set up the user interface from Designer.
    self.ui.setupUi(self)
    for i in range(0, len(ci)):
        item = str(ci[i][0])
        price = str(ci[i][1])
        self.ui.itemsComboBox.addItem(item)
    price = str(self.getPrice())
    gPrice = "$" + price
    print gPrice
    self.ui.priceFieldLabel.setText(gPrice)
    self.ui.itemsComboBox.currentIndexChanged['QString'].connect(self.updateItems)
    self.ui.availableSpaceFieldLabel.setText(space)
    canBuy = str(funcs.youCanAfford(cash, price))
    self.ui.canAffordFieldLabel.setText(canBuy)
    qtyToBuy = self.ui.buySpinBox.value()

The code that handles the dialog itself is

def buyDialog(self):
    global current, price, qtyToBuy
    dialog = BuyDialog()
    result = dialog.exec_()

    if result:
        dialogResult = (current, price, qtyToBuy)
        print dialogResult #debug
        return dialogResult

current comes from a combo box in the dialog, and price comes from a list lookup against current. I know the dialog updates correctly, as the values returned for current and price are correct. However, qtyToBuy always returns 0. The only way I've gotten it to return anything different is by calling setValue() on it when it's initiated. Everywhere I've looked, I get the impression I'm the only person that's had this problem, as I can find nothing else regarding this issue. Does anyone have any idea what the problem is?

Bendustries
  • 71
  • 1
  • 3
  • 10
  • Please show the actual sequence of code where you getting the `value()` of spin box and using it. – qurban Jan 09 '14 at 11:10
  • For now, the only output is `print dialogResult`. I'm debugging by outputting to the command line. Since I don't know Python/PyQt that well, I'm going slowly and making sure the data is returning correctly before I put it into use anywhere else. – Bendustries Jan 09 '14 at 11:18
  • Why using global variables instead of a method in BuyDialog wrapping self.ui.buySpinBox.value()? And where exactly is the line `qtyToBuy = self.ui.buySpinBox.value()` executed? – Frank Osterfeld Jan 09 '14 at 11:32
  • Sorry, I misunderstood - Where it's actually being retrieved is within the `__init__` function of the dialog itself. I'll update the question. – Bendustries Jan 09 '14 at 11:33
  • the `__init__` function is executed before the dialog is shown, so if you assign to qtyToBuy there, any user action will be without effect. The safest is to just call value() after the dialog was closed. – Frank Osterfeld Jan 09 '14 at 11:35
  • @Frank Osterfeld - I had that same thought, except that the values for `current` (from a combo in the dialog) and `price` (looked up from a dict containing all the items in the combo box and their corresponding prices) are being returned correctly, which (I think) tells me that user interaction on the dialog can be returned to the main GUI window. Also, from my shaky understanding of PyQt, calling the value() in the result (eg, OK was pressed) is calling value() upon the dialog being closed. – Bendustries Jan 09 '14 at 11:39
  • @Frank Osterfeld - As to your first comment, I attempted that as well, with `def buyQty(self): qtyToBuy = self.ui.buySpinBox.value() return qtyToBuy'`. I would call that, and call setValue() on the variable created from the call to buyQty – Bendustries Jan 09 '14 at 11:53

1 Answers1

1

As @Frank pointed out that since the value() of the spinBox is retrieved before the dialog is shown, the user input in the spinBox will not affect the value of qtyToBuy, it will always give you the default value of spinBox (which is 0 in your case). To retrieve the user specified value from the spinBox, you should retrieve the value after the dialog is closed (i.e. the user presses Ok on the dialog)

def buyDialog(self):
    global current, price, qtyToBuy
    dialog = BuyDialog()
    result = dialog.exec_()

    qtyToBuy = dialog.ui.buySpinBox.value() # add this line here

    if result:
        dialogResult = (current, price, qtyToBuy)
        print dialogResult #debug
        return dialogResult

Now the print statement will print the value which was the value in spinBox when the user pressed Ok on the dialog.

qurban
  • 3,885
  • 24
  • 36
  • Absolutely dead on. Thank you so much - I've been banging my head on this for far longer than I'd care to admit. – Bendustries Jan 09 '14 at 13:30