Textctrl OnBackspace Event Availabiliy Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Emerald2240
Knows some wx things
Knows some wx things
Posts: 30
Joined: Tue Dec 11, 2018 1:38 pm

Textctrl OnBackspace Event Availabiliy

Post by Emerald2240 » Tue Apr 09, 2019 1:44 pm

Hi guys i'm a beginner level wxwidgets programmer. i recently embarked on a small project that calculates your GPA based on Grades and Credit load and i stumbled upon a little bug, I use a 'OnTextCtrltext' function to automatically grab Values once input. my problem is in the case of the user making an error and deciding to click the backspace button, the previous values already previously calculated and the clearing of whats been previously input won't be recorded. I've tried looking up a function that reads a OnBackspace event but to no avail. here's some code to help explain what i mean.

Code: Select all

double totalcreditload = 1;
double totalgrades = 0;
double GPA() {
return (totalgrades/totalcreditload);

void gp_calculatorFrame::OnTextCtrl27Text(wxCommandEvent& event)
{
    if (TextCtrl27->GetValue() == "A" || TextCtrl27->GetValue() == "a"){
       totalgrades += (4 * credit26);
    };

    if (TextCtrl27->GetValue() == "B" || TextCtrl27->GetValue() == "b"){
        totalgrades += (3 * credit26);
        };

        if (TextCtrl27->GetValue() == "C" || TextCtrl27->GetValue() == "c"){
       totalgrades += (2 * credit26);
        };

         if (TextCtrl27->GetValue() == "D" || TextCtrl27->GetValue() == "d"){
        totalgrades += (1 * credit26);
        };

        if (TextCtrl27->GetValue() == "F" || TextCtrl27->GetValue() == "f"){
       totalgrades += (0 * credit26);
        };
        wxString transformer;
        transformer<<GPA();
    TextCtrl14->SetValue(transformer);
}
//Once the letter is input its value is automatically recorded and if its cleared and a new value is input, it saves it as well :!:

Any info on a Backspace event or anything similar would be most appreciated. thanks in advance.
Last edited by doublemax on Tue Apr 09, 2019 3:48 pm, edited 1 time in total.
Reason: Added code tags

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3594
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Textctrl OnBackspace Event Availabiliy

Post by ONEEYEMAN » Tue Apr 09, 2019 2:18 pm

Hi,
This is a VERY BAD design.
You should have a button on you frame which will read "Calculate" or some something like this.

In the button pres event handler you will check whether all fields required hasw the values and then calculate the needed value.

You can filter the characters types in the EVT_TEXT event handler, but not the calculation.

Thank you.

User avatar
doublemax
Moderator
Moderator
Posts: 14300
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Textctrl OnBackspace Event Availabiliy

Post by doublemax » Tue Apr 09, 2019 3:47 pm

You could catch the wxEVT_CHAR event (-> wxKeyEvent), but that shouldn't be necessary. The wxEVT_TEXT event should always be called when the value of the text field changes, that means also in response to backspace.

But i think there is a more serious flaw in the code: totalgrades gets incremented each time the value of the text field changes. E.g. if you change the value from A to B, it will increase over and over again. That can't be right. You need to keep a copy of the old, unmodified value at all time and then calculate the new value based on that.

On a side note: There is a lot of duplicate code in the small code fragment you've shown. That's usually a good indicator that things can get simplified.

E.g.:

Code: Select all

// create upercase version of the string
wxString grade_str = TextCtrl27->GetValue().Upper();

// is string is not empty, get the first char
const char grade = grade_str.len() > 0 ? grade_str[0] : 0;

int factor = 0;
switch( grade )
{
  case 'A': factor = 4; break;
  case 'B': factor = 3; break;
  case 'C': factor = 2; break;
  case 'D': factor = 1; break;
  // what about E?
  case 'F': factor = 0; break;
}

totalgrades_new = totalgrades_old + (factor * credit26);
Use the source, Luke!

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3594
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Textctrl OnBackspace Event Availabiliy

Post by ONEEYEMAN » Tue Apr 09, 2019 4:47 pm

doublemax,
doublemax wrote:
Tue Apr 09, 2019 3:47 pm
You could catch the wxEVT_CHAR event (-> wxKeyEvent), but that shouldn't be necessary. The wxEVT_TEXT event should always be called when the value of the text field changes, that means also in response to backspace.

But i think there is a more serious flaw in the code: totalgrades gets incremented each time the value of the text field changes. E.g. if you change the value from A to B, it will increase over and over again. That can't be right. You need to keep a copy of the old, unmodified value at all time and then calculate the new value based on that.
My solution is much simpler and easier to follow. ;-)
Besides it is much better design - enter all the data required and then calculate. No calculator I know including a simple hand-help will do math on the fly - only whe the user press '=' sign on the keyboard. :)
doublemax wrote:
Tue Apr 09, 2019 3:47 pm
On a side note: There is a lot of duplicate code in the small code fragment you've shown. That's usually a good indicator that things can get simplified.

E.g.:

Code: Select all

// create upercase version of the string
wxString grade_str = TextCtrl27->GetValue().Upper();

// is string is not empty, get the first char
const char grade = grade_str.len() > 0 ? grade_str[0] : 0;

int factor = 0;
switch( grade )
{
  case 'A': factor = 4; break;
  case 'B': factor = 3; break;
  case 'C': factor = 2; break;
  case 'D': factor = 1; break;
  // what about E?
  case 'F': factor = 0; break;
}

totalgrades_new = totalgrades_old + (factor * credit26);

User avatar
doublemax
Moderator
Moderator
Posts: 14300
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Textctrl OnBackspace Event Availabiliy

Post by doublemax » Tue Apr 09, 2019 5:06 pm

My solution is much simpler and easier to follow.
That depends on the circumstances. Sometimes it might be useful to perform immediate updates when a value changes. Sometimes it makes sense to do it only when the focus changes. And sometimes you have an explicit "Apply" (or similar) button.

Without knowing the bigger picture, i didn't want to make a suggestion in any direction.
Use the source, Luke!

Emerald2240
Knows some wx things
Knows some wx things
Posts: 30
Joined: Tue Dec 11, 2018 1:38 pm

Re: Textctrl OnBackspace Event Availabiliy

Post by Emerald2240 » Tue Apr 09, 2019 7:06 pm

ONEEYEMAN wrote:
Tue Apr 09, 2019 2:18 pm
Hi,
This is a VERY BAD design.
You should have a button on you frame which will read "Calculate" or some something like this.

In the button pres event handler you will check whether all fields required hasw the values and then calculate the needed value.

You can filter the characters types in the EVT_TEXT event handler, but not the calculation.

Thank you.
Thanks Sir. What you said works but i guess you could say i'm trying to make the program as appealing as possible. If all else fails I'll get back to it.
Thanks Again.

Emerald2240
Knows some wx things
Knows some wx things
Posts: 30
Joined: Tue Dec 11, 2018 1:38 pm

Re: Textctrl OnBackspace Event Availabiliy

Post by Emerald2240 » Tue Apr 09, 2019 7:22 pm

doublemax wrote:
Tue Apr 09, 2019 3:47 pm
You could catch the wxEVT_CHAR event (-> wxKeyEvent), but that shouldn't be necessary. The wxEVT_TEXT event should always be called when the value of the text field changes, that means also in response to backspace.

But i think there is a more serious flaw in the code: totalgrades gets incremented each time the value of the text field changes. E.g. if you change the value from A to B, it will increase over and over again. That can't be right. You need to keep a copy of the old, unmodified value at all time and then calculate the new value based on that.

On a side note: There is a lot of duplicate code in the small code fragment you've shown. That's usually a good indicator that things can get simplified.

E.g.:

Code: Select all

// create upercase version of the string
wxString grade_str = TextCtrl27->GetValue().Upper();

// is string is not empty, get the first char
const char grade = grade_str.len() > 0 ? grade_str[0] : 0;

int factor = 0;
switch( grade )
{
  case 'A': factor = 4; break;
  case 'B': factor = 3; break;
  case 'C': factor = 2; break;
  case 'D': factor = 1; break;
  // what about E?
  case 'F': factor = 0; break;
}

totalgrades_new = totalgrades_old + (factor * credit26);
Thanks Sir. #-o Guess the switch function could work there too. thanks again for the extra functions, can't wait to test them out.

Emerald2240
Knows some wx things
Knows some wx things
Posts: 30
Joined: Tue Dec 11, 2018 1:38 pm

Re: Textctrl OnBackspace Event Availabiliy

Post by Emerald2240 » Tue Apr 09, 2019 8:01 pm

doublemax wrote:
Tue Apr 09, 2019 3:47 pm
You could catch the wxEVT_CHAR event (-> wxKeyEvent), but that shouldn't be necessary. The wxEVT_TEXT event should always be called when the value of the text field changes, that means also in response to backspace.

But i think there is a more serious flaw in the code: totalgrades gets incremented each time the value of the text field changes. E.g. if you change the value from A to B, it will increase over and over again. That can't be right. You need to keep a copy of the old, unmodified value at all time and then calculate the new value based on that.

On a side note: There is a lot of duplicate code in the small code fragment you've shown. That's usually a good indicator that things can get simplified.

E.g.:

Code: Select all

// create upercase version of the string
wxString grade_str = TextCtrl27->GetValue().Upper();

// is string is not empty, get the first char
const char grade = grade_str.len() > 0 ? grade_str[0] : 0;

int factor = 0;
switch( grade )
{
  case 'A': factor = 4; break;
  case 'B': factor = 3; break;
  case 'C': factor = 2; break;
  case 'D': factor = 1; break;
  // what about E?
  case 'F': factor = 0; break;
}

totalgrades_new = totalgrades_old + (factor * credit26);
Tried this, multiple errors, fixed some but got stuck at this:" error: switch quantity not an integer"

User avatar
doublemax
Moderator
Moderator
Posts: 14300
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Textctrl OnBackspace Event Availabiliy

Post by doublemax » Tue Apr 09, 2019 8:32 pm

Sorry, i wrote that blindly, without checking if it compiles.

char works for me in a switch, but you can just change it into an integer.

Code: Select all

int grade = grade_str.length() > 0 ? grade_str[0] : 0;
Use the source, Luke!

Post Reply