首页 文章

Rust&GTK 3.如何创建包含glib :: Value类型的元素的数组,可以将其转换为&[&ToValue]类型?

提问于
浏览
3

我正在使用Rust和GTK 3绑定创建GUI应用程序(称为Gtk-rs或rust-gnome) . 我想使用方法insert_with_values将一些数据插入 gtk::ListStoreGtkListStore

Working sample, but only one column: 如果我有一列,我可以插入数据:

let type_of_a_column = &[gtk::Type::U32];
let data_for_column_1 = (2 as u32).to_value();
let model_list_of_data = ListStore::new(type_of_a_column);
model_list_of_data.insert_with_values(None, &[0 as u32], &[&data_for_column_1]);

但是,如果我有更多列,我不知道如何移交更多数据 . 我知道在内部它应该调用gtk_list_store_insert_with_valuesv()所以我可能需要一个数组或切片,但如果我做了类似的事情:

Wanted to pass two elements in array, not working

let type_of_a_column = &[gtk::Type::U32, gtk::Type::I64];
let data_for_column_1 = (2 as u32).to_value();
let data_for_column_2 = (4 as i64).to_value();
let array_of_data = [&data_for_column_1, &data_for_column_2];
let model_list_of_data = ListStore::new(type_of_a_column);
model_list_of_data.insert_with_values(None, &[1 as u32], &[&array_of_data]);

它在编译期间给了我:

错误:特征界限[&glib :: Value; 2]:不满足glib :: IsA <glib :: Object> [E0277]

我不知道如何克服它 .

不工作MCVE

main.rs

extern crate gtk;

use gtk::prelude::*;
use gtk::{Box, ListStore, Orientation, TreeView, Window, WindowType};

fn exit_app() -> gtk::prelude::Inhibit {
    // Stop the main loop.
    gtk::main_quit();
    // Let the default handler destroy the window.
    Inhibit(false)
}

fn main() {
    if gtk::init().is_err() {
        panic!("Failed to initialize GTK.");
    }

    println!("Version of GTK+3:\t{}.{}",
             gtk::get_major_version(),
             gtk::get_minor_version());
    let window = Window::new(WindowType::Toplevel);
    window.set_title("Exercises with GtkTreeView and GtkListStore");
    window.set_position(gtk::WindowPosition::Center);
    window.connect_delete_event(|_, _| exit_app());

    let box_container = Box::new(Orientation::Vertical, 0);
    let view_list = TreeView::new();

    let types_inside_columns = &[gtk::Type::U32, gtk::Type::I64];
    let data_in_column_1 = (2 as u32).to_value();
    let data_in_column_2 = (4 as i64).to_value();

    let array_of_data = [&data_in_column_1, &data_in_column_2];

    let model_list_of_data = ListStore::new(types_inside_columns);

    model_list_of_data.insert_with_values(Some(0), &[0 as u32, 1 as u32], &[&array_of_data]);

    view_list.set_model(Some(&model_list_of_data));
    box_container.pack_start(&view_list, false, false, 0);
    window.add(&box_container);

    window.show_all();
    gtk::main();
}

Cargo.toml

[package]
name = "test_of_gtk_3"
version = "0.0.1"
authors = ["wm_obsd"]

[dependencies.gtk]
version = "0.1.0"
features = ["v3_16"]

[[bin]]
name = "main"
path = "src/main.rs"

1 回答

  • 2

    最终,你最有可能想写这样的东西:

    model_list_of_data.insert_with_values(Some(0), &[0, 1], &[&2u32, &4i64]);
    

    让我们稍微分解一下函数定义:

    fn insert_with_values(&self,
                          position: Option<u32>,
                          columns: &[u32],
                          values: &[&ToValue])
                          -> TreeIter;
    

    此函数对 ListStore ,可选位置,零或多列作为整数,以及对特征ToValue的零或多个引用进行不可变引用 .

    什么类型实现 ToValue ?文件说:

    impl<T> ToValue for Option<T> where T: SetValueOptional
    impl<T> ToValue for T where T: SetValue + ?Sized
    impl ToValue for Value
    

    看一下SetValue,我们可以看到它是为原始整数类型实现的 .

    u32i64 实现 SetValue 以来,它们也实现 ToValue . 对该数字的引用也可以隐含地强制转换为对该特征的引用 .

    通过此更改,窗口出现,但是......

    blank window

    你必须从这里弄清楚GTK的奥秘!

相关问题