动态QTableWidg上的跨列单元验证

2024-04-19 18:53:07 发布

您现在位置:Python中文网/ 问答频道 /正文

动态表单元验证的推荐方法。你知道吗

场景:我有一个QDialog,根据不同的下拉选择动态添加一个或多个表。因为表是动态添加的,所以标准单元格单击信号是不够的。它只提供行和列,我需要知道除了行和列之外还单击了哪个表。更具体地说,我有两列整数值。更改其中一列中的单元格时,这些单元格必须在有效范围内,并且第二列中单元格的值必须大于等于第一列中单元格的值。你知道吗

我对Python还比较陌生,但我的想法是需要创建一个类,用所需的附加信息扩展QTableWidgetItem,并发送一个自定义信号,然后将其连接到对话框中的一个槽中。我尝试了以下代码的几种变体,但都不太正确:

class SmartCell(QtCore.QObject):

    valueChanged = QtCore.pyqtSignal(str)  # Signal to be emitted when value changes.

    def __init__(self, tbl, rowname, colname, value):
        QtGui.QTableWidgetItem.__init__(self)
        self.tbl_name = tbl
        self.row_name = rowname
        self.col_name = colname
        # self.setText(value)
        self.__value = value

    @property
    def value(self):
        return self.__value

    @value.setter
    def value(self, value):
        if self.__value != value:
            self.__value = value
            # self.setText(value)
            signal = self.tbl_name + ":" + self.row_name + ":" + self.col_name + ":" + self.text()
            self.valueChanged.emit(signal)

然后在对话框中,将SmartCell引用作为sCell导入后:

item = sCell(obj_name, f.part_name, "start_frame", str(f.start_frame))
item.valueChanged.connect(self.frame_cell_changed)
tbl.setItem(rowcounter, 1, item)
item = sCell(obj_name, f.part_name, "end_frame", str(f.end_frame))
item.valueChanged.connect(self.frame_cell_changed)
tbl.setItem(rowcounter, 2, item)

Tags: nameself信号valuedef动态itemframe
1条回答
网友
1楼 · 发布于 2024-04-19 18:53:07

您的任务变得太复杂了,验证委托应该做什么,而不是对QTableWidgetItems使用create-post-validation逻辑。你知道吗

import random
from PyQt4 import QtCore, QtGui

class LimistDelegate(QtGui.QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        editor = super(LimistDelegate, self).createEditor(parent, option, index)
        if index.column() in (1, 2):
            editor = QtGui.QSpinBox(parent)
        return editor

    def setEditorData(self, editor, index):
        if index.column() in (1, 2):
            m = 0 if index.column() == 1 else index.sibling(index.row(), 1).data()
            M = index.sibling(index.row(), 2).data() if index.column() == 1 else 360
            if hasattr(m, 'toPyObject'):
                m = m.toPyObject()
            if hasattr(M, 'toPyObject'):
                M = M.toPyObject()
            editor.setMinimum(m)
            editor.setMaximum(M)
        super(LimistDelegate, self).setEditorData(editor, index)

def create_table():
    nrows, ncols = random.randrange(3, 6), 3
    table = QtGui.QTableWidget(nrows, ncols)
    for r in range(nrows):
        text = "description {}".format(r)
        a = random.randrange(0, 180) 
        b = random.randrange(a, 360)
        for c, val in enumerate([text, a, b]):
            it = QtGui.QTableWidgetItem()
            it.setData(QtCore.Qt.DisplayRole, val) # set data on item
            table.setItem(r, c, it)
    return table

class Widget(QtGui.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        vlay = QtGui.QVBoxLayout(self)
        for _ in range(4):
            table = create_table()
            delegate = LimistDelegate(table) # create delegate
            table.setItemDelegate(delegate)  # set delegate
            vlay.addWidget(table)

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

相关问题 更多 >