How to right justify numeric data in gtk rs List Store

Hello All,
I have another Rust noob question. I have been playing around with the GTK RS tutorials this weekend and have learned quite a bit already. I am using a modified version of this file: https://github.com/gtk-rs/examples/blob/master/src/bin/list_store.rs

I have simplified it quite a bit for my usage to just show some basic US State data that can be sorted by state name, state population, state area or date stated was admitted to the union by clicking the desired column header. This all works well.

I can successfully align.justify the column headers but not the data. I would like to right justify the numeric data (population & area) and center the date information.

I am assuming I need to put the alignment code here at d.population & d.area for right justify and d.date for center justify.

for (_, d) in data.iter().enumerate() {
    let values: [&dyn ToValue; 4] = [
        &d.state,
        &d.population,
        &d.area,
        &d.date,
    ];
    store.set(&store.append(), &col_indices, &values);
}

But I cannot find what I am looking for. I was really hoping something as simple as d.area.set_alignment(1.0) would work :pleading_face:

Thanks for any help!
Jerry

My complete code:

extern crate gio;
extern crate gtk;

use gtk::prelude::*;
use std::rc::Rc;
use std::env::args;
use gio::prelude::*;

#[repr(i32)]
enum Columns {
    State,
    Population,
    Area,
    Date,
}

fn build_ui(application: &gtk::Application) {
    let window = gtk::ApplicationWindow::new(application);

    window.set_title("List Store");
    window.set_border_width(10);
    window.set_position(gtk::WindowPosition::Center);
    window.set_default_size(300, 500);

    let vbox = gtk::Box::new(gtk::Orientation::Vertical, 8);
    window.add(&vbox);

    let label = gtk::Label::new(Some("US State Facts"));
    vbox.add(&label);

    let sw = gtk::ScrolledWindow::new(None::<&gtk::Adjustment>, None::<&gtk::Adjustment>);
    sw.set_shadow_type(gtk::ShadowType::EtchedIn);
    sw.set_policy(gtk::PolicyType::Never, gtk::PolicyType::Automatic);
    vbox.add(&sw);

    let model = Rc::new(create_model());
    let treeview = gtk::TreeView::new_with_model(&*model);
    treeview.set_vexpand(true);

    sw.add(&treeview);

    add_columns(&treeview);

    window.show_all();
}

struct Data {
    state: String,
    population: u32,
    area: u32,
    date: String,
}

fn create_model() -> gtk::ListStore {

    let col_types: [gtk::Type; 4] = [
        gtk::Type::String,
        gtk::Type::U32,
        gtk::Type::U32,
        gtk::Type::String,
    ];

    let data: [Data; 14] = [
        Data {
            state: "Alabama".to_string(),
            population: 4887871,
            area: 125767,
            date: "1819.12.14".to_string(),
        },

        Data {
            state: "Alaska".to_string(),
            population: 737438,
            area: 1723337,
            date: "1959.01.03".to_string(),
        },

        Data {
            state: "Arkansas".to_string(),
            population: 3013825,
            area: 137732,
            date: "1836.06.15".to_string(),
        },

        Data {
            state: "Arizona".to_string(),
            population: 7171646,
            area: 295234,
            date: "1912.02.14".to_string(),
        },

        Data {
             state: "California".to_string(),
             population: 39557045,
             area: 423972,
             date: "1850.09.09".to_string(),
        },

        Data {
            state: "Colorado".to_string(),
            population: 5695564,
            area: 269601,
            date: "1876.08.01".to_string(),
        },

        Data {
             state: "Connecticut".to_string(),
             population: 3572665,
             area: 14357,
             date: "1788.01.09".to_string(),
        },

        Data {
            state: "Delaware".to_string(),
            population: 967171,
            area: 6446,
            date: "1787.12.07".to_string(),
        },

        Data {
            state: "Maine".to_string(),
            population: 1338404,
            area: 91633,
            date: "1820.03.15".to_string(),
        },

        Data {
             state: "Maryland".to_string(),
             population: 6042718,
             area: 32131,
             date: "1788.04.28".to_string(),
        },

        Data {
            state: "Massachusetts".to_string(),
            population: 6902149,
            area: 27336,
            date: "1788.02.06".to_string(),
        },

        Data {
            state: "Michigan".to_string(),
            population: 9998915,
            area: 250487,
            date: "1837.01.26".to_string(),
        },

        Data {
            state: "Missouri".to_string(),
            population: 6126452,
            area: 180540,
            date: "1821.08.10".to_string(),
        },

        Data {
             state: "Nebraska".to_string(),
             population: 1929268,
             area: 200330,
             date: "1867.03.01".to_string(),
        },
    ];

    let store = gtk::ListStore::new(&col_types);

    let col_indices: [u32; 4] = [0, 1, 2, 3];

    for (_, d) in data.iter().enumerate() {
        let values: [&dyn ToValue; 4] = [
            &d.state,
            &d.population,
            &d.area,
            &d.date,
        ];
        store.set(&store.append(), &col_indices, &values);
    }

    store
}

fn add_columns(treeview: &gtk::TreeView) {

    // Column for state name
    {
        let renderer = gtk::CellRendererText::new();
        let column = gtk::TreeViewColumn::new();
        column.pack_start(&renderer, true);
        column.set_title("State");
        column.add_attribute(&renderer, "text", Columns::State as i32);
        column.set_sort_column_id(Columns::State as i32);
        column.set_fixed_width(150);
        column.set_alignment(0.0);
        treeview.append_column(&column);
    }

    // Column for population
    {
        let renderer = gtk::CellRendererText::new();
        let column = gtk::TreeViewColumn::new();
        column.pack_start(&renderer, true);
        column.set_title("Population");
        column.add_attribute(&renderer, "text", Columns::Population as i32);
        column.set_sort_column_id(Columns::Population as i32);
        column.set_fixed_width(150);
        column.set_alignment(1.0);
        treeview.append_column(&column);
    }

    // Column for area
    {
        let renderer = gtk::CellRendererText::new();
        let column = gtk::TreeViewColumn::new();
        column.pack_start(&renderer, true);
        column.set_title("Area");
        column.add_attribute(&renderer, "text", Columns::Area as i32);
        column.set_sort_column_id(Columns::Area as i32);
        column.set_fixed_width(150);
        column.set_alignment(1.0);
        treeview.append_column(&column);
    }

    // Column for date
    {
        let renderer = gtk::CellRendererText::new();
        let column = gtk::TreeViewColumn::new();
        column.pack_start(&renderer, true);
        column.set_title("Date");
        column.add_attribute(&renderer, "text", Columns::Date as i32);
        column.set_sort_column_id(Columns::Date as i32);
        column.set_fixed_width(150);
        column.set_alignment(0.5);
        treeview.append_column(&column);
    }
}


fn main() {
    let application = gtk::Application::new(
        Some("com.github.gtk-rs.examples.list-store"),
        Default::default(),
    )
    .expect("Initialization failed...");

    application.connect_startup(|app| {
        build_ui(app);
    });

    application.connect_activate(|_| {});

    application.run(&args().collect::<Vec<_>>());
}
1 Like

You will probably need to apply some sort of css to the cells.

A Python GTK expert on stack overflow got me the answer which is here - https://stackoverflow.com/questions/57135341/how-to-right-justify-numeric-data-in-list-store-tree-view-using-gtk-rs - if anyone needs this info for the future.

good

1 Like