You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gtk对话框点击OK时TreeView可编辑单元格数据丢失,如何保存?

问题描述

使用Rust开发带OK按钮的gtk::Dialog,对话框内包含带有可编辑单元格的TreeView。编辑单元格时点击OK按钮,新输入的数据会丢失,尝试在dialog.connect_delete_event中添加CellTextRender.stop_editing方法未解决问题。

精简代码:

let dialog = gtk::Dialog::with_buttons(Some("Пользователи"), parent,
                                       gtk::DialogFlags::MODAL, &[("OK", gtk::ResponseType::Ok)]);

let table = gtk::TreeView::new();
let user_model = gtk::ListStore::new(&[glib::Type::STRING]);
table.set_model(Some(&user_model));
table.set_enable_grid_lines(gtk::TreeViewGridLines::Both);
let user_name_render = gtk::CellRendererText::new();
 
user_name_render.set_editable(true);

let user_name_column = gtk::TreeViewColumn::with_attributes("Username", &user_name_render, &[("text", 0 as i32)]);
user_name_column.set_resizable(true);
table.append_column(&user_name_column);  
dialog.content_area().pack_start(&table, true, true, 0);     
dialog.show_all();
dialog.run();

问题现象:编辑单元格输入新内容后点击OK,单元格内容恢复为编辑前的值。

解决方案

问题根源是点击OK时,单元格编辑状态未结束,新数据未提交到ListStore。需在对话框响应OK前,强制结束编辑并提交数据。

实现步骤

  • 监听对话框的response信号,替代直接调用dialog.run(),以便在响应触发时先处理数据提交。
  • 在响应回调中,获取TreeView当前的编辑控件,调用stop_editing(true)提交编辑内容。

修改后的完整代码

use gtk::{prelude::*, DialogFlags, ResponseType};

fn main() {
    gtk::init().unwrap();
    let parent = gtk::Window::new(gtk::WindowType::Toplevel);

    let dialog = gtk::Dialog::with_buttons(Some("Пользователи"), Some(&parent),
                                           DialogFlags::MODAL, &[("OK", ResponseType::Ok)]);

    let table = gtk::TreeView::new();
    let user_model = gtk::ListStore::new(&[glib::Type::STRING]);
    // 添加测试数据
    user_model.insert_with_values(None, &[0], &[&"test_user"]);
    
    table.set_model(Some(&user_model));
    table.set_enable_grid_lines(gtk::TreeViewGridLines::Both);
    let user_name_render = gtk::CellRendererText::new();
 
    user_name_render.set_editable(true);

    let user_name_column = gtk::TreeViewColumn::with_attributes("Username", &user_name_render, &[("text", 0 as i32)]);
    user_name_column.set_resizable(true);
    table.append_column(&user_name_column);  
    dialog.content_area().pack_start(&table, true, true, 0);     
    dialog.show_all();

    // 监听对话框响应事件
    dialog.connect_response(move |dialog, response| {
        if response == ResponseType::Ok {
            // 强制结束编辑并提交数据到模型
            if let Some(editable) = table.get_editable() {
                editable.stop_editing(true);
            }
            // 验证数据保存结果(可选)
            if let Some(mut iter) = user_model.iter_first() {
                let saved_name = user_model.get_value(&iter, 0).get::<String>().unwrap();
                println!("已保存用户名: {}", saved_name);
            }
        }
        dialog.close();
    });

    gtk::main();
}

关键说明

  • table.get_editable():获取TreeView中处于编辑状态的控件,若没有正在编辑的内容则返回None。
  • editable.stop_editing(true):参数true表示提交编辑内容到数据模型,false则丢弃编辑内容。
  • 使用connect_response拦截响应事件,确保在对话框关闭前完成数据提交,避免数据丢失。

内容的提问来源于stack exchange,提问作者Rishat Sagidullin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 17:20:16