Combobox 如何在Rust'中的ListStore中添加ListStore;s gtk rs绑定?

Combobox 如何在Rust'中的ListStore中添加ListStore;s gtk rs绑定?,combobox,rust,gtk3,treemodel,rust-gnome,Combobox,Rust,Gtk3,Treemodel,Rust Gnome,我想创建一个包含组合框的TreeView程序 为了获得GTKCellRenderCombo的数据,我需要一个GtkTreeModel*,但我不知道如何在ListStore中添加ListStore 现在我只有一个简单的树状视图。我希望在1列(标题“f64”)内有一个组合框: 我曾尝试将gtk::Type:BaseBoxed添加到types\u inner\u列中,然后将一个装箱的ListStore添加到array\u数据中,但是Box方法无法成功地将转换为值() 增加: 此程序在运行时处于恐慌状态

我想创建一个包含
组合框的
TreeView
程序

为了获得
GTKCellRenderCombo
的数据,我需要一个
GtkTreeModel*
,但我不知道如何在
ListStore
中添加
ListStore

现在我只有一个简单的
树状视图
。我希望在1列(标题“f64”)内有一个组合框

我曾尝试将
gtk::Type:BaseBoxed
添加到
types\u inner\u列中
,然后将一个装箱的
ListStore
添加到
array\u数据中
,但是
Box
方法无法成功地将
转换为
值()

增加: 此程序在运行时处于恐慌状态:

extern crate gtk;
use gtk::prelude::*;
use gtk::{ComboBox, ListStore, Orientation, TreeView, TreeViewColumn, Window, WindowType};


fn main()
{
    gtk::init().expect("Failed to initialize GTK");
    let window = Window::new(WindowType::Toplevel);
    window.set_position(gtk::WindowPosition::Center);    
    window.set_title("Rust&GTK+3");
    window.set_position(gtk::WindowPosition::Center);
    window.connect_delete_event(|wind, _| {
        let (szerokosc,wysokosc) =  wind.get_size();
        println!("Width {} Height {}",szerokosc,wysokosc);
        // Stop the main loop.
        gtk::main_quit();
        // Let the default handler destroy the window.
        Inhibit(false)
    });
    let main_box = gtk::Box::new(Orientation::Vertical,0);
    let view_list = TreeView::new();
    {
        let types_inside_columns = &[gtk::Type::U32,gtk::Type::F64,gtk::Type::Pointer];
        let model_list_of_data = ListStore::new(types_inside_columns);
        for liczba in 0..10 {
            let model_for_combo = ListStore::new(types_inside_columns);
            let array_of_data = [&(liczba.to_value()) as &ToValue,
            &((liczba as f64 * 1.5).to_value()) as &ToValue,
            ];
            let typ_iter = model_list_of_data.insert_with_values(None,&[0,1],&array_of_data);
            model_list_of_data.set_value(&typ_iter,2, &model_for_combo.to_value() as &gtk::Value);
        }
        view_list.set_model(Some(&model_list_of_data));
        let object_to_render_cells : gtk::CellRendererText = gtk::CellRendererText::new();
        object_to_render_cells.set_visible(true);
        let view_column= TreeViewColumn::new();
        view_column.set_expand(true);
        view_column.set_visible(true);
        view_column.set_title("u32");
        view_column.pack_start(&object_to_render_cells,true);
        view_column.add_attribute(&object_to_render_cells,"text",0);
        view_list.append_column(&view_column);
        //second column
        let object_to_render_cells_2 : gtk::CellRendererCombo = gtk::CellRendererCombo::new();
        let view_column_2 = TreeViewColumn::new();
        view_column_2.set_expand(true);
        view_column_2.set_visible(true);
        view_column_2.set_title("f64");
        view_column_2.pack_start(&object_to_render_cells_2,true);
        view_column_2.add_attribute(&object_to_render_cells_2,"text",1);
        view_list.append_column(&view_column_2);
    }
    view_list.expand_all();
    main_box.add(&view_list);
    window.add(&main_box);
    window.show_all();
    gtk::main();
}
类型问题 如果要在另一个
gtk::ListStore
中存储
gtk::ListStore
,则不指定
gtk::Type::Pointer
,需要使用最后一个变量。您可以在运行时使用获取
gtk::ListStore
的类型。遗憾的是,由于类型号的变化,我在编译时找不到这样做的方法

let model = ListStore::new(&[Type::U8]);
println!("{:?}", model.to_value_type()); // Other(139977306752544)
println!("{:?}", model.to_value()); // Value(((GtkListStore*) 0x7f4f01b9a060))
// get type at runtime
let liststore_type = model.to_value_type();
let model = ListStore::new(&[Type::U32, Type::F64, liststore_type]);
现在,您可以插入子模型,就像您希望使用
ToValue::to_value
所做的那样

使用gtk::CellRenderCombo
但是,您写道您希望在一行中使用组合框,可能用于编辑数字。为此,您不需要嵌套
gtk::ListStore
。您需要一个用于gtk::TreeView的模型,另一个用于选项

let model_list_of_data = ListStore::new(&[gtk::Type::U32, gtk::Type::String]);
let model_for_combo = ListStore::new(&[gtk::Type::String]);


for liczba in 0..10 {
    let integer = liczba.to_value();
    let float = format!("{}", liczba as f64 * 1.5).to_value();

    model_list_of_data.insert_with_values(None, &[0, 1], &[&integer, &float]);
    model_for_combo.insert_with_values(None, &[0], &[&float]);
}

// code for first column not changed

let object_to_render_cells_2: gtk::CellRendererCombo = gtk::CellRendererCombo::new();
object_to_render_cells_2.set_visible(true);
object_to_render_cells_2.set_property_editable(true);
// use the combo model for the options
object_to_render_cells_2.set_property_model(Some(&model_for_combo.upcast()));
// display the options of the first column in the combo model
object_to_render_cells_2.set_property_text_column(0);
let view_column_2 = TreeViewColumn::new();
view_column_2.set_expand(true);
view_column_2.set_visible(true);
view_column_2.set_title("f64");
view_column_2.pack_start(&object_to_render_cells_2, false);
// the data for each row is in the second column in the tree model
view_column_2.add_attribute(&object_to_render_cells_2, "text", 1);
view_list.append_column(&view_column_2);
您可能已经注意到,我使用字符串而不是普通浮点。这有两个原因:

  • 使用
    格式,输出中不包括不必要的零
  • 对于普通浮动,gtk将显示组合,但如果您单击其中一个组合,它将崩溃
  • let model_list_of_data = ListStore::new(&[gtk::Type::U32, gtk::Type::String]);
    let model_for_combo = ListStore::new(&[gtk::Type::String]);
    
    
    for liczba in 0..10 {
        let integer = liczba.to_value();
        let float = format!("{}", liczba as f64 * 1.5).to_value();
    
        model_list_of_data.insert_with_values(None, &[0, 1], &[&integer, &float]);
        model_for_combo.insert_with_values(None, &[0], &[&float]);
    }
    
    // code for first column not changed
    
    let object_to_render_cells_2: gtk::CellRendererCombo = gtk::CellRendererCombo::new();
    object_to_render_cells_2.set_visible(true);
    object_to_render_cells_2.set_property_editable(true);
    // use the combo model for the options
    object_to_render_cells_2.set_property_model(Some(&model_for_combo.upcast()));
    // display the options of the first column in the combo model
    object_to_render_cells_2.set_property_text_column(0);
    let view_column_2 = TreeViewColumn::new();
    view_column_2.set_expand(true);
    view_column_2.set_visible(true);
    view_column_2.set_title("f64");
    view_column_2.pack_start(&object_to_render_cells_2, false);
    // the data for each row is in the second column in the tree model
    view_column_2.add_attribute(&object_to_render_cells_2, "text", 1);
    view_list.append_column(&view_column_2);