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
相关产品推荐
相关产品推荐

