5

I'm searching for a possible method to only allow numeric input in a Gtk::Entry widget, without relying on SpinButtons. The matter is, I found a template for this (link), but it just won't work. I can compile it along my other code, but if I want to declare an instance with

NumericEntry<int> int_entry(1,0,10);

it tells me

expected ‘,’ or ‘...’ before numeric constant

The second part is, that I have no clear idea how to pack this entry, because I get a

can't convert to widget

error when using

functionname.pack_start(int_entry())

I guess there is a stupid error an my part (bad combination of C++ and Gtkmm newbie), so any help is appreciated.

H.B.
  • 166,899
  • 29
  • 327
  • 400
AcMNPV
  • 53
  • 1
  • 3
  • 3
    Philosophy moment: I'm never a fan of restricting inputs like this. What if I have the number I want already on the clipboard, with a couple of extra letters, and copy/paste it...then I'll delete the numbers? Text inputs should be text inputs--check it before you proceed and flag it if it's no good--but don't write brittle hooks that cripple the standard widget behavior. You cause more problems than you solve. – HostileFork says dont trust SE Apr 23 '12 at 12:20
  • Thanks for this idea, I will see what I get implemented first. My reasoning for the numeric input is the context: the user should give kinetic data for an enzyme and that is always purely numeric, so I thought it would be easier to just restrict the input. – AcMNPV Apr 24 '12 at 10:12
  • 1
    There's a lot more we can do with software when we shift from thinking about how to *restrict* input to thinking about how to *process* input. For an example: http://ux.stackexchange.com/questions/2898/how-to-create-bands-of-number-ranges-for-a-field/ – HostileFork says dont trust SE Apr 24 '12 at 11:12
  • ok, I will see that I just check the inputs in the widgets then, thanks for the help and sorry that I didn't reply for a while. Can someone close this question? – AcMNPV May 06 '12 at 10:05

2 Answers2

4

One way to only allow numbers is to subclass Gtk::Entry and override the on_insert_text() virtual function. In that virtual function, you can validate the text entered and only call the base class's on_insert_text() when the text validates.

void NumberEntry::on_insert_text(const Glib::ustring& text, int* position)
{
    // allow only numbers to be entered
    if (contains_only_numbers(text))
        Gtk::Entry::on_insert_text(text, position);
}
kalev
  • 1,925
  • 1
  • 15
  • 12
  • 1
    In case anyone is struggling with defining a "contains_only_numbers" function... `bool NumberEntry::contains_only_numbers(const Glib::ustring& text) { for(int i = 0; i < text.length(); i++) { if(Glib::Unicode::isdigit(text[i]) == false) return false; } return true; }` – CodeMouse92 Jun 17 '15 at 21:41
1

Here is a solution without subclassing. This is written in Rust but it should work the same in other languages.

fn is_non_ascii_digit(c: char) -> bool {
    !c.is_ascii_digit()
}
fn entry_disallow(entry: &gtk::Entry, pattern: fn(char) -> bool) {
    entry.connect_insert_text(move |entry, text, position| {
        if text.contains(pattern) {
            glib::signal::signal_stop_emission_by_name(entry, "insert-text");
            entry.insert_text(&text.replace(pattern, ""), position);
        }
    });
}

// To use it
entry_disallow(&entry, is_non_ascii_digit);
Jan Schär
  • 808
  • 6
  • 9