【问题标题】:QTableWidget- automatic formula driven cellQTableWidget - 自动公式驱动的单元格
【发布时间】:2017-12-23 11:38:18
【问题描述】:

是否可以将一个单元格设为公式驱动单元格并自动更新?类似于 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])

【问题讨论】:

  • 您能解释一下您需要操作哪些单元格以及如何操作吗?
  • 在你的图中,你想让第三个单元格等于第一个单元格之间的第二个单元格吗?
  • Cell (2,0) 或 'Specific Power(HP/MMSCFD)' 当用户在 Cell (0,0)-'Flow (MMSCFD) 和 Cell (1,0 ) - '生命值'。 Cell (2,0) 从 Cell(0,0) 和 Cell(1,0) 中获取值。它划分 Cell(1,0)/Cell(0,0) 或者换句话说它需要 HP/Flow(MMSCFD)。
  • 如果您正在查看屏幕截图,我希望第三个单元格等于第二个单元格/第一个单元格
  • 一次查询是否所有单元格都只有数字条目?

标签: python python-3.x pyqt pyqt5 qtablewidget


【解决方案1】:

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

除了不存在用户将不同值放入浮动对象的问题之外,我们还将使用 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

【讨论】:

  • 方法 createEditor 究竟做了什么?
  • 每次编辑 QTableWidget 文本时,通常都会将小部件更改为另一个合适的小部件,如果您意识到在编辑时出现 QLineEdit 而不是 QLabel,那么 createEditor 是创建编辑小部件的函数,在我们的案例 QLineEdit,以及我们放置验证器的 QLineEdit。
  • 为了更好地理解,您可以将 createEditor 更改为我添加的新功能。
  • 有没有办法从 QtDesigner 中的 CustomTableWidget 类中的 Ui 类中访问变量?
  • 你在Qt Designer中推广过QTableWidget吗?
【解决方案2】:

将单元格连接到其他单元格 EditingFinished 信号

【讨论】:

  • 考虑到我的 QTableWidget 是动态创建的,如何将一个单元格连接到另一个单元格? self.tableWidget[i].item(1,0).EditingFinished.connect(self.tableWidget[i].item(2,0))?
  • 是的,单元格的数量已定义,但我的 QTableWidget 正在创建多次,这就是为什么会有'self.tableWidget[i]'。我正在寻找一种将单元格 (1,0) 连接到 (2,0) 的方法。我在问你如何将两个细胞连接在一起。这样当用户输入(1,0)时,单元格(2,0)将(1,0)除以另一个单元格。是否有关于如何使用 EditingFinished 连接单元的文档?
  • 实际上一共有10个单元格,但我只关心标记为'OEM'的第一列。 “OEM”列中有 5 个单元格。试图划分单元格(1,0)/单元格(0,0),我希望它在用户在标记为“HP”的行中输入值时立即更新
  • 每个单元格都有一个小部件项。我认为您可以将它们连接起来。我还会考虑从 QTableWidget 派生并在那里而不是在表数组之外进行连接。或者,也许是时候看看 QTableView 并构建自己的模型了。然后模型 setData() 可以更简单地评估您的公式。如果您需要,它还允许您在不同的视图中显示相同的数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-12
相关资源
最近更新 更多