如何编辑列公式以便自动计算?

Posted

技术标签:

【中文标题】如何编辑列公式以便自动计算?【英文标题】:How to edit column formula so it can be calculated automatically? 【发布时间】:2019-04-07 10:35:21 【问题描述】:

我正在使用 python 制作一个项目,它的行为类似于 excel,例如,当我在我的单元格中输入一些数字时,它将在另一个单元格中使用定义的算法自动计算

我已经尝试实施一些想法,但我被卡住了。我只能做简单的计算,比如加法和乘法。当我尝试编辑代码以允许它进行任何形式的复杂计算时遇到问题。

...

def print_it(self,no):

        if no.column()==2:
            return
        try:
            add = 10
            for column in range(0,2):
                try:
                    add*=int(self.table.item(no.row(),column).text())
                except:
                    pass  
             self.table.setItem(no.row(),2,QtWidgets.QTableWidgetItem(str(add)))
        except Exception as E:
            print(E)

当公式为 (X^2 + Y^2) 时,我可以获得 IKS 值的正确方法是什么?

这是我的桌子

【问题讨论】:

我认为您需要重新表述您的问题(我不确定我是否真的在这里看到了问题)并提供 MCVE (***.com/help/mcve)。 哦,谢谢你提醒我,我很抱歉我的英语不好..@Omar 【参考方案1】:

您必须使用 itemChanged 信号通知您某些项目的更改,然后您必须验证它是否是您想要的列,如果是,则进行相应的计算。

from PyQt5 import QtCore, QtGui, QtWidgets

# https://***.com/a/55523206/6622587
class DoubleDelegate(QtWidgets.QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        editor = QtWidgets.QDoubleSpinBox(parent)
        editor.setFrame(False)
        editor.setMinimum(-1.7976931348623157e308)
        editor.setMaximum(1.7976931348623157e308)
        editor.setSizePolicy(
            QtWidgets.QSizePolicy.Ignored, editor.sizePolicy().verticalPolicy()
        )
        return editor


class EmptyDelegate(QtWidgets.QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        return None


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.tablewidget = QtWidgets.QTableWidget(4, 7)
        self.tablewidget.setHorizontalHeaderLabels(
            ["X", "Y", "f", "A", "IKS", "PGA", "GSS"]
        )
        self.tablewidget.itemChanged.connect(self.on_itemChanged)
        for col in (0, 1):
            delegate = DoubleDelegate(self.tablewidget)
            self.tablewidget.setItemDelegateForColumn(col, delegate)
        for col in (4,):
            delegate = EmptyDelegate(self.tablewidget)
            self.tablewidget.setItemDelegateForColumn(col, delegate)

        self.setCentralWidget(self.tablewidget)

    @QtCore.pyqtSlot("QTableWidgetItem*")
    def on_itemChanged(self, item):
        if item.column() in (0, 1):
            self.calculate_iks(item.row())

    def calculate_iks(self, row):
        self.tablewidget.blockSignals(True)
        for col in (0, 1):
            it = self.tablewidget.item(row, col)
            if it is None:
                it = QtWidgets.QTableWidgetItem("0")
                self.tablewidget.setItem(row, col, it)
        self.tablewidget.blockSignals(False)
        it_x = self.tablewidget.item(row, 0)
        it_y = self.tablewidget.item(row, 1)
        x = float(it_x.text())
        y = float(it_y.text())
        iks = x ** 2 + y ** 2
        it_iks = self.tablewidget.item(row, 4)
        if it_iks is None:
            it_iks = QtWidgets.QTableWidgetItem()
            self.tablewidget.setItem(row, 4, it_iks)
        it_iks.setText(str(iks))


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

如果您想计算gss = iks * pga,那么您应该执行以下操作:

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.tablewidget = QtWidgets.QTableWidget(4, 7)
        self.tablewidget.setHorizontalHeaderLabels(
            ["X", "Y", "f", "A", "IKS", "PGA", "GSS"]
        )
        self.tablewidget.itemChanged.connect(self.on_itemChanged)
        for col in (0, 1, 5):
            delegate = DoubleDelegate(self.tablewidget)
            self.tablewidget.setItemDelegateForColumn(col, delegate)
        for col in (4, 6,):
            delegate = EmptyDelegate(self.tablewidget)
            self.tablewidget.setItemDelegateForColumn(col, delegate)

        self.setCentralWidget(self.tablewidget)

    @QtCore.pyqtSlot("QTableWidgetItem*")
    def on_itemChanged(self, item):

        if item.column() in (0, 1):
            self.calculate_iks(item.row())
        elif item.column() in (4, 5):
            self.calculate_gss(item.row())

    # ...

    def calculate_gss(self, row):
        self.tablewidget.blockSignals(True)
        for col in (4, 5, 6):
            it = self.tablewidget.item(row, col)
            if it is None:
                it = QtWidgets.QTableWidgetItem("0")
                self.tablewidget.setItem(row, col, it)
        self.tablewidget.blockSignals(False)
        it_iks = self.tablewidget.item(row, 4)
        it_pga = self.tablewidget.item(row, 5)
        iks = float(it_iks.text())
        pga = float(it_pga.text())
        gss = iks*pga
        it_gss = self.tablewidget.item(row, 6)
        it_gss.setText(str(gss))

我建议分析解决方案而不只是应用,因为这是SO的思想,如果在计算iks和gss的情况下进行,您可以看到有很多相似之处,以便您可以重构代码来做其他计算方法很简单。

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.tablewidget = QtWidgets.QTableWidget(4, 7)
        self.tablewidget.setHorizontalHeaderLabels(
            ["X", "Y", "f", "A", "IKS", "PGA", "GSS"]
        )
        self.tablewidget.itemChanged.connect(self.on_itemChanged)
        for col in (0, 1, 5):
            delegate = DoubleDelegate(self.tablewidget)
            self.tablewidget.setItemDelegateForColumn(col, delegate)
        for col in (4, 6):
            delegate = EmptyDelegate(self.tablewidget)
            self.tablewidget.setItemDelegateForColumn(col, delegate)

        self.setCentralWidget(self.tablewidget)

        self.calculates = [
            
                "inputs": (0, 1),  # X, Y
                "output": 4,  # IKS
                "function": lambda X, Y: X ** 2 + Y ** 2,
            ,
            
                "inputs": (4, 5),  # IKS, PGA
                "output": 6,  # GSS
                "function": lambda IKS, PGA: IKS * PGA,
            ,
        ]

    @QtCore.pyqtSlot("QTableWidgetItem*")
    def on_itemChanged(self, item):
        for c in self.calculates:
            inputs = c["inputs"]
            output = c["output"]
            function = c["function"]
            if item.column() in inputs:
                self.calculate(item.row(), inputs, output, function)

    def calculate(self, row, inputs, output, function):
        self.tablewidget.blockSignals(True)
        for col in (*inputs, output):
            it = self.tablewidget.item(row, col)
            if it is None:
                it = QtWidgets.QTableWidgetItem("0")
                self.tablewidget.setItem(row, col, it)
        self.tablewidget.blockSignals(False)
        values = [float(self.tablewidget.item(row, i).text()) for i in inputs]
        result = function(*values)
        it_out = self.tablewidget.item(row, output)
        it_out.setText(str(result))

【讨论】:

我可以再问一下吗? IKS 和 PGA 值已完成,但在计算 GSS 值时我很困惑。公式是 GSS = (PGA * IKS) @eyllanesc @SenthiaIna 在应用我的解决方案之前,您必须正确理解它,否则想象您每次想要添加功能时都会要求我实现一些新的东西。我已经花时间来实现你指出的计算,除了给出一个概括。

以上是关于如何编辑列公式以便自动计算?的主要内容,如果未能解决你的问题,请参考以下文章

excel表格怎么计算除法

excel 公式?

在线等一个excel公式!满意立即给分谢谢!!!

出生年月提取年龄公式

请问如何从Excel一列单元格中,用公式提取唯一值?

wps文档里面有公式么?