如何编辑列公式以便可以自动计算? [英] How to edit column formula so it can be calculated automatically?

查看:132
本文介绍了如何编辑列公式以便可以自动计算?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm making a project using python where it can behave similar to excel, for example when I input some numbers in my cell, it will be automatically calculated in another cell with a defined algorithm.

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

I have tried implementing some ideas but I get stuck. I can only do simple calculations like adittion and multiplication. I have a problem when I try to edit the code to allow it to do any form of complex calculation.

...

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值?

这是我的桌子

推荐答案

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

You have to use the itemChanged signal to notify you of the change of some item, then you have to validate if it is the column you want and if so, then make the corresponding calculations.

from PyQt5 import QtCore, QtGui, QtWidgets

# https://stackoverflow.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,则应执行以下操作:

If you want to calculate gss = iks * pga then you should do the following:

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的情况下做到了这一点,那么您会发现有很多相似之处,因此您可以重组代码来完成其他计算方式很简单.

I recommend analyzing the solution and not only apply since that is the idea of SO, if it is done in the case of calculating iks and gss you can see that there are many similarities, so that you can restructure the code to do other calculations In a simple way.

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))

这篇关于如何编辑列公式以便可以自动计算?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆