python - QTableWidget-自动公式驱动单元格

标签 python python-3.x pyqt pyqt5 qtablewidget

是否可以使一个单元格成为公式驱动单元格并使其自动更新?与 Excel 类似。

例如,我希望用户填写两个单元格,然后当用户填写这两个单元格时,第三个单元格将自动划分。我希望它不连接到按钮。

QTable截图

TableWidget 代码:

self.tableWidget = {}
for i in range(int(self.numberLine.text())):
    self.tableWidget[i] = QTableWidget()
    self.tableWidget[i].setRowCount(5)
    self.tableWidget[i].setColumnCount(3)
    self.tableWidget[i].setHorizontalHeaderLabels(['OEM (Case {})'.format(i+1), 'ZVI (Case {})'.format (i+1), 'Improvement % '])
    self.tableWidget[i].setVerticalHeaderLabels(['Flow (MMSCFD)', 'HP', 'Specific Power (HP/MMSCFD)', 'Discharge Temp (F)', ''])
    self.tableWidget[i].setFixedSize(QtCore.QSize(480, 180))
    self.gridLayout_14.addWidget(self.tableWidget[i])

最佳答案

一个优雅的解决方案是创建一个继承自QTableWidget的自定义类,在其中连接itemChanged信号,每次单元格更改值时都会发出该信号(这会返回更改的项目,但仅使用它来验证默认列是否已更改)。

除了不存在用户将不同值放置到 float 中的问题之外,我们还将使用 QDoubleValidator,为此我们创建一个自定义 QItemDelegate。

class FloatDelegate(QItemDelegate):
    def __init__(self, _from, _to, _n_decimals, parent=None):
        QItemDelegate.__init__(self, parent=parent)
        self._from = _from
        self._to = _to
        self._n_decimals = _n_decimals

    def createEditor(self, parent, option, index):
        lineEdit = QLineEdit(parent)
        _n_decimals = 2
        validator = QDoubleValidator(self._from, self._to, self._n_decimals, lineEdit)
        lineEdit.setValidator(validator)
        return lineEdit


class CustomTableWidget(QTableWidget):
    _from = 0
    _to = 10**5
    _n_decimals = 2
    def __init__(self, i,  parent=None):
        QTableWidget.__init__(self, 5, 3, parent=parent)
        self.setItemDelegate(FloatDelegate(self._from, self._to, self._n_decimals, self))
        self.setHorizontalHeaderLabels(['OEM (Case {})'.format(i+1), 'ZVI (Case {})'.format (i+1), 'Improvement % '])
        self.setVerticalHeaderLabels(['Flow (MMSCFD)', 'HP', 'Specific Power (HP/MMSCFD)', 'Discharge Temp (F)', ''])
        self.setFixedSize(QSize(480, 180))
        self.itemChanged.connect(self.onItemChanged)

    def onItemChanged(self, item):
        # items (2, 0) = (1, 0) / (0, 0)
        if item.column() == 0 and (item.row() == 0 or item.row()==1):
            num = self.item(1, 0)
            den = self.item(0, 0)
            if num and den:
                resp = float(num.data(Qt.DisplayRole))/float(den.data(Qt.DisplayRole))
                rest_string = str(round(resp, self._n_decimals))
                it = QTableWidgetItem(rest_string, QTableWidgetItem.Type)
                self.setItem(2, 0, it)

示例:

class Widget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent=parent)
        self.setLayout(QGridLayout())
        for i in range(2):
            self.layout().addWidget(CustomTableWidget(i))

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = Widget()
    window.show()
    sys.exit(app.exec_())

就您而言:

self.tableWidget = {}
for i in range(int(self.numberLine.text())):
    self.tableWidget[i] = CustomTableWidget(i)
    self.gridLayout_14.addWidget(self.tableWidget[i])

除了使用验证器之外,还有另一个选项,我们可以将 QLineEdit 更改为 QDoubleSpinBox。

def createEditor(self, parent, option, index):
    w = QDoubleSpinBox(parent)
    _n_decimals = 2
    w.setMinimum(self._from)
    w.setMaximum(self._to)
    w.setDecimals(self._n_decimals)
    return w

关于python - QTableWidget-自动公式驱动单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45169547/

相关文章:

python - *** web3.exceptions.BadFunctionCallOutput : Could not transact with/call contract function, 合约部署正确且链同步了吗?

python - 对使用 lambda 函数的错误感到困惑

python - matplotlib 程序运行时窗口无响应

python - 在多核上运行 Python

python - 如何为 href 指定方法名称?

python - 在地下的pygame blit中导致地下被锁定的错误

python - 是否有 subprocess.call 的安静版本?

python - 如何使用 Python 3 将文本写入以二进制模式打开的文件中?

python - Matplotlib 热图,垂直底部标签

python - 弹出警告框