Search code examples
pythonpython-2.7pyqtpyqt4

what's the matter in this Python code?


I'm writing a unit converter using PyQt 4. Here, I'm facing a problem.

class UnitConverter(QtGui.QComboBox):
    def __init__(self, parent=None):
        super(UnitConverter, self).__init__(parent)
        self.unitsdict = {
            "mass": {"g": 1, "kg": 1000, "t": 1000000, "oz": 28.3495231, "lb": 453.59237},
            "pressure": {"pa": 1, "kpa": 1000, "mpa": 1000000, "bar": 100000, "atm": 101325,
                        "tor": 133.3223684, "psi": 6894.757, "at": 98066.5}
        }

    def combo(self, measurement):
        for key in self.unitsdict[measurement]:
            self.addItem(self.tr(key), self.unitsdict[measurement][key])

    def comboConnect(self, table, row, column):
        self.names = locals()
        #tablevar = "self.table_" + str(row) + "_" + str(column)
        self.rowvar = "self.row_" + str(row) + "_" + str(column)
        self.columnvar = "self.column_" + str(row) + "_" + str(column)
        self.names[self.rowvar] = row
        self.names[self.columnvar] = column
        self.table = table
        self.base = self.itemData(self.currentIndex())
        self.currentIndexChanged.connect(self.change)

    def change(self):
        tobase = self.itemData(self.currentIndex())
        try:
            self.value = float(self.table.item(self.names[self.rowvar], self.names[self.columnvar]).text())
            tovalue = '%f' % (self.value * self.base / tobase)
            changeitem = QtGui.QTableWidgetItem(str(tovalue))
            self.table.setItem(self.names[self.rowvar], self.names[self.columnvar], changeitem)
        except:
            pass
        self.base = tobase

I want it can automatically calculate the result when I change the index of the combobox. enter image description here

It works when there is only one QTableWidgetItem connect to it.

table = QTableWidget(10, 3)
combo = Unit converter()
combo.combo("pressure")
table.setCellWidget(5, 0, combo)
combo.comboConnect(table, 5, 1)

But when I connect another QTableWidgetItem, the first one unexpectedly doesn't work any more.

table = QTableWidget(10, 3)
combo = Unit converter()
combo.combo("pressure")
table.setCellWidget(5, 0, combo)
combo.comboConnect(table, 5, 1)
combo.comboConnect(table, 5, 2)

So, I want to know what the problem is. Or, how can I do to make the table(5, 1) work again?


Solution

  • the main problem is that you are overwriting many variables so you only see the last saved data, for example self.rowvar and self.columnvar save the last row and column, instead of updating you must add it to a list or something similar.

    class UnitConverter(QtGui.QComboBox):
        def __init__(self, table, parent=None):
            super(UnitConverter, self).__init__(parent)
            self.unitsdict = {
                "mass": {"g": 1, "kg": 1000, "t": 1000000, "oz": 28.3495231, "lb": 453.59237},
                "pressure": {"pa": 1, "kpa": 1000, "mpa": 1000000, "bar": 100000, "atm": 101325,
                             "tor": 133.3223684, "psi": 6894.757, "at": 98066.5}
            }
            self.table = table
            self.base = -1
            self.items = []
            self.currentIndexChanged.connect(self.change)
    
        def combo(self, measurement):
            for key in self.unitsdict[measurement]:
                self.addItem(self.tr(key), self.unitsdict[measurement][key])
            self.base = self.itemData(self.currentIndex())
    
        def comboConnect(self, row, column):
            self.items.append((row, column))
    
        def change(self, ix,):
            tobase = self.itemData(ix)
            factor = self.base / tobase
            self.base = tobase
    
            for r, c in self.items:
                it = self.table.item(r, c)
                try:
                    value = float(it.text())
                    tovalue = '%f' % (value * factor)
                    it.setText(tovalue)
                except:
                    pass
    
    
    if __name__ == '__main__':
        import sys
    
        app = QtGui.QApplication(sys.argv)
        table = QtGui.QTableWidget(10, 3)
        combo = UnitConverter(table)
        combo.combo("pressure")
        table.setCellWidget(5, 0, combo)
        combo.comboConnect(5, 1)
        combo.comboConnect(5, 2)
        table.show()
        sys.exit(app.exec_())