Subclassing QTableWidget

本文介绍如何通过子类化QTableWidget实现自定义单元格类,详细讲解了setItemPrototype函数的应用,以及如何设置单元格公式进行计算。


Subclassing QTableWidget

在空的Cell 上输入文字时,QTableWidget 会自动创建QTableWidgetItem 以存储文本。

QTableWidgetItem 不是Widget 类,它是纯数据类。Cell 类派生自QTableWidgetItem


Spreadsheet::Spreadsheet(QWidget *parent)
     setItemPrototype(new Cell);
     setSelectionMode(ContiguousSelection);  // allow a single rectangular selection  ???

      
用户在Cell 上输入数据时,我们希望QTableWidget 自动创建Cell 类而不是QTableWidgetItem 用来存储文本,setItemPrototype() 函数可以完成你的愿望。

setRowCount(0);
setColumnCount(0);
setRowCount(RowCount);
setColumnCount(ColumnCount);

要清除Cell 数据先把行列设成0,再恢复原值既可。

QTableWidget 拥有多个子Widget,顶部横向的QHeaderView,左侧纵向的QHeaderView,还有两个QScrollBars(位于右边和下面);

QTableWidget 的中心位置是一个viewport,这里是绘制单元格的地方。

QTableWidgetItem::formula(),多数情况下formula 和text 是一样的,比如输入"hello",输出也是"hello"。

但是另一些例外:输入"1.5",formula 返回double 值1.5,并且以右对齐的方式在单元格中渲染。

If the formula starts with a single quote,formula 返回的是text。如输入"12345",返回字符串"12345"

void Spreadsheet::setFormula(int row, int column,
                             const QString &formula)
{
    Cell *c = cell(row, column);
    if (!c) {
        c = new Cell;
        setItem(row, column, c);
    }
    c->setFormula(formula);  // c 这个单元格的值从A1 和A2 计算出来,用公式"=A1+A2"
}


如果formula 以一个"=" 开始,将被当做一个计算式。例如, A1,A2 两个单元格的数据分别是"12" 和"6",公式 "=A1+A2" 计算出 18


QTableWidgetItem 不只包含数据,还存储了一些属性,如字符串,字体,颜色,icon,以及一个指向QTableWidget 的指针。

<think>好的,我现在需要处理用户的问题,他想在C#中使用Keras的Model SubclassingAPI来训练DNN模型的示例代码或教程。但根据之前的对话,Keras本身是Python库,C#无法直接调用,所以之前的解决方案是通过Python训练模型,导出后用TensorFlow.NET在C#中进行推理。现在用户可能希望更进一步,是否有可能在C#中直接进行模型训练,而不仅仅是推理? 首先,我需要确认用户的需求。用户之前的提问是关于如何在C#中使用ModelSubclassing API,而回答中已经指出C#无法直接调用Keras的API,只能通过跨语言协作。现在用户再次询问,可能希望找到在C#中直接训练的方法,或者是否有新的库支持这一点。接下来,我需要查阅现有的资料。根据引用内容,Keras的Model SubclassingAPI是Python特有的功能,用于构建自定义模型。C#中并没有原生的Keras支持,但可能有第三方库如TensorFlow.NET,它允许在C#中使用TensorFlow的功能。但TensorFlow.NET是否支持类似Keras的高级API,特别是ModelSubclassing呢? 查看TensorFlow.NET的文档,发现它主要提供TensorFlow的低级API绑定,虽然支持构建和训练模型,但可能没有直接实现Keras的Model SubclassingAPI。因此,在C#中直接使用ModelSubclassing API可能不可行。用户可能需要使用TensorFlow.NET的低级API来构建类似的结构,或者继续使用Python进行模型定义和训练,然后在C#中加载进行推理。用户可能希望有一个端到端的C#解决方案,但技术限制使得这不太现实。因此,回答需要明确说明这一点,并提供替代方案,比如在C#中使用TensorFlow.NET的低级API构建模型,或者继续使用Python训练后导出。另外,用户提供的引用内容提到,Keras的Sequential模型和Functional API在Python中的使用方式,以及Model Subclassing的方法。但这些都是Python代码,无法直接转换为C#。因此,需要强调跨语言协作的必要性,并可能提供如何在C#中构建类似结构的示例,但使用TensorFlow.NET的方式。 可能还需要考虑用户是否混淆了训练和推理的步骤,或者是否有其他库如ML.NET可以用于C#中的深度学习训练,但ML.NET主要针对传统机器学习,而非复杂的深度学习模型。 总结,回答需要明确在C#中无法直接使用Keras的ModelSubclassing API,但可以通过TensorFlow.NET的低级API构建和训练模型,或者继续使用Python进行训练,C#进行推理。同时,提供相应的代码示例,说明如何在C#中构建类似的DNN模型,尽管方式不同。</think>### C#与Keras Model Subclassing API的协同方案 由于Keras的Model Subclassing API是Python生态的专有特性,C#无法直接调用。但可通过以下两种方式实现**跨语言协作**或**等效建模**: --- #### 一、跨语言协作方案(推荐) **核心流程**: 1. **在Python中完成模型定义与训练** 2. **导出为SavedModel格式** 3. **在C#中通过TensorFlow.NET加载模型进行推理** ##### 1. Python端自定义模型(Model Subclassing API) ```python import tensorflow as tf class CustomDNN(tf.keras.Model): def __init__(self, input_dim=32, num_classes=10): super().__init__() self.dense1 = tf.keras.layers.Dense(64, activation='relu', input_shape=(input_dim,)) self.dropout = tf.keras.layers.Dropout(0.5) self.dense2 = tf.keras.layers.Dense(num_classes, activation='softmax') def call(self, inputs, training=False): x = self.dense1(inputs) if training: x = self.dropout(x) return self.dense2(x) # 训练并导出模型 model = CustomDNN() model.compile(optimizer='adam', loss='sparse_categorical_crossentropy') model.fit(x_train, y_train, epochs=5) tf.saved_model.save(model, "custom_dnn_model") ``` ##### 2. C#端加载模型推理(TensorFlow.NET) ```csharp using Tensorflow; using static Tensorflow.Binding; var graph = new Graph(); var session = tf.Session(graph); var model = tf.saved_model.loader.load(session, ["serve"], "custom_dnn_model"); // 输入输出张量名称需与Python导出时一致 var input_tensor = graph.OperationByName("serving_default_dense_input"); var output_tensor = graph.OperationByName("StatefulPartitionedCall"); // 构造输入数据(示例) var input_data = new float[,] { { 1.0f, 2.0f, ..., 32.0f } }; var tensor = tf.constant(input_data); // 执行推理 var results = session.run(output_tensor.outputs[0], new FeedItem(input_tensor.outputs[0], tensor)); ``` --- #### 二、C#原生建模方案(通过TensorFlow.NET) 若需**完全在C#中实现模型训练**,需使用TensorFlow.NET的低级API构建等效模型: ```csharp using Tensorflow; using static Tensorflow.Binding; // 定义模型结构 var model = new Sequential(); model.add(tf.keras.layers.Dense(64, activation: "relu", input_shape: new Shape(32))); model.add(tf.keras.layers.Dropout(0.5f)); model.add(tf.keras.layers.Dense(10, activation: "softmax")); // 编译模型 model.compile(optimizer: tf.keras.optimizers.Adam(), loss: tf.keras.losses.SparseCategoricalCrossentropy(), metrics: new[] { "accuracy" }); // 训练模型(需准备数据) model.fit(x_train, y_train, epochs: 5, batch_size: 32); // 保存模型 model.save("csharp_dnn_model"); ``` **关键差异**: - 使用`Sequential`类而非Model Subclassing API - 层定义通过方法链式调用实现 - 动态图支持有限(需提前定义静态计算图)[^1] --- ### 对比分析 | 方案 | 优势 | 局限性 | |---------------------|-------------------------------|----------------------------| | 跨语言协作 | 支持复杂自定义模型 | 需维护Python/C#两套代码 | | C#原生建模 | 全流程C#实现 | 无法完全复现Subclassing特性 | --- ### 技术要点解析 1. **TensorFlow.NET的层定义** - 层参数需显式指定(如`input_shape`) - 激活函数通过字符串名称传递(如`activation: "relu"`) 2. **数据格式转换** - C#数组需转换为`Tensor`对象: ```csharp var tensor = tf.constant(new float[,] { { 1.0f, 2.0f }, { 3.0f, 4.0f } }); ``` 3. **性能优化** - 使用`tf.data.Dataset`加速数据管道: ```csharp var dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)) .shuffle(1000) .batch(32); ``` --- ### 常见问题解答 #### Q1: TensorFlow.NET是否支持动态图模式? 目前仅支持**静态图模式**,需预先定义计算图结构。动态图功能(如Eager Execution)尚在开发中[^2]。 #### Q2: 如何实现自定义损失函数? 需继承`Tensorflow.Keras.Losses.Loss`类: ```csharp public class CustomLoss : Loss { public override Tensor Apply(Tensor y_true, Tensor y_pred, bool from_logits = false) { return tf.reduce_mean(tf.square(y_true - y_pred)); } } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值