QT: How to retrieve floating point value from QLineEdit form fields - qt

how do i get/convert the text from a QLineEdit field.
the code below is operated by a button / slot.
but when compiled and pressing the button, 0.00000000000 shows up.
no calculation takes place, whatever numbers i type into fields.
float solution = 0.0;
QString value_A = ui->doubleSpinBox_1->text();
float floatvalue_A = value_A.toFloat();
QString value_B = ui->lineEdit_1->text();
float floatvalue_B = value_B .toFloat();
if(floatvalue_A == 0.0){
QMessageBox::information(this, "empty","",QMessageBox::Ok);
}
solution = (floatvalue_A * floatvalue_B);
ui->lineEdit_result_1->setText(QString::number(solution, 'f', 10));
the code editor indicates:
ui->lineEdit_result_1->setText(QString::number(solution, 'f', 10)); warning: implicit conversion increases floating-point precision: 'float' to 'double'
here also:
if(floatvalue_A == 0.0){ warning: implicit conversion increases floating-point precision: 'float' to 'double'
QMessageBox::information(this, "empty","",QMessageBox::Ok);
}
what am i doing wrong?
i used the QMessageBox to find out where the code is going wrong, no values are retrieved from the form fields.

I just run this code in a MainWindow and it works as expected
connect(ui->pushButton, &QPushButton::clicked, this, [&]() {
auto f1 = ui->lineEdit->text().toFloat();
auto f2 = ui->lineEdit_2->text().toFloat();
auto f3 = ui->doubleSpinBox->value();
auto sum = f1 + f2 + f3;
ui->lineEdit_3->setText(QString::number(sum));
});

I believe the first warning comes from the fact that QString::number doesn't have an overload for float, so the "solution" variable is getting promoted to a double. You can cast it explicitly to get rid of the warning:
QString::number ((double) solution, 'f', 10)
Alternately, you could declare "solution" as a double and simply work with double values throughout.
The second statement generates a conversion warning because "0.0" is a double which then forces floatvalue_A to promote to a double. There's a discussion about the implied type of 0 here:
C++ difference between 0 and 0.0
If you stay with floats in your code, you can use "0.0f" to force the constant to be a float rather than a double, and that should get rid of the warning. If you switch your variables to double throughout, then it will automatically go away.

you are comparing double against a float, and that cause a precision lost, that is the reason why.
0.0 is a literal double until you don explicity tell qt you want a float
like doing
auto myFloat{0.0f};
aside note: you shouldnt do comparations like this:
floatvalue_A == 0.0

Related

QT Using calculations for vertices [duplicate]

I'm learning C++, and encountering these problems in a simple program, so please help me out.
This is the code
#include<iostream>
using std::cout;
int main()
{ float pie;
pie = (22/7);
cout<<"The Value of Pi(22/7) is "<< pie<<"\n";
return 0;
}
and the output is
The Value of Pi(22/7) is 3
Why is the value of Pi not in decimal?
That's because you're doing integer division.
What you want is really float division:
#include<iostream>
using std::cout;
int main()
{
float pie;
pie = float(22)/7;// 22/(float(7)) is also equivalent
cout<<"The Value of Pi(22/7) is "<< pie<<"\n";
return 0;
}
However, this type conversion: float(variable) or float(value) isn't type safe.
You could have gotten the value you wanted by ensuring that the values you were computing were floating point to begin with as follows:
22.0/7
OR
22/7.0
OR
22.0/7.0
But, that's generally a hassle and will involve that you keep track of all the types you're working with. Thus, the final and best method involves using static_cast:
static_cast<float>(22)/7
OR
22/static_cast<float>(7)
As for why you should use static_cast - see this:
Why use static_cast<int>(x) instead of (int)x?
pie = (22/7);
Here the division is integer division, because both operands are int.
What you intend to do is floating-point division:
pie = (22.0/7);
Here 22.0 is double, so the division becomes floating-point division (even though 7 is still int).
The rule is that IF both operands are integral type (such as int, long, char etc), then it is integer division, ELSE it is floating-point division (i.e when even if a single operand is float or double).
Use:
pi = 22/7.0
If u give the two operands to the / operator as integer then the division performed will be integer division and a float will not be the result.

scanning a float, getting seemingly random values

I was given an assignment to create a procedure that scans a float, called getfloat.
for some reason, I am getting random values. If I enter "1" it prints 49.Why does this happen? And also, when i input values, I can't see them on the screen? when I use scanf for example i see what i hit, on the little black screen. but now the screen is just blank, and when i click enter it shows a bad output:
Example - input: -1. Output: 499.00000
Here is my code:
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <ctype.h>
void getfloat(float* num);
void main()
{
float num=0;
printf("Enter the float\n");
getfloat(&num);
printf("\nThe number is %lf\n",num);
getch();
}
void getfloat(float* num)
{
float c,sign=1,exponent=10;
c=getch();
if((!isdigit(c))&&(c!='+')&&(c!='-')) //if it doesnt start with a number a + or a -, its not a valid input
{
printf("Not a number\n");
return;
}
if(c=='-') //if it starts with a minus, make sign negative one, later multiply our number by sign
sign=-1;
for(*num=0;isdigit(c);c=getch())
*num=(*num*10)+c; //scan the whole part of the number
if(c!='.') //if after scanning whole part, c isnt a dot, we finished
return;
do //if it is a dot, scan fraction part
{
c=getch();
if(isdigit(c))
{
*num+=c/exponent;
exponent*=10;
}
}while(isdigit(c));
*num*=sign;
}
There are a number of issues.
1) Your posted code does not match your example "input: -1. Output: 499.00000", I get 0 due the lack of a getch() after finding a '-'. See #6.
1) 'c' is a character. When you enter '1', c took on a code for the letter 1, which in your case being ASCII coding, is 49. To convert a digit from its ASCII value to a number value, subtract 48 (the ASCII code for the letter '0', often done as c - '0'
*num=(*num*10)+c;
*num+=c/exponent;
becomes
*num = (*num*10) + (c-'0');
*num += (c-'0')/exponent;
2) Although you declare c as a float, recommend you declare it as an int. int is the return type from getch().
3) Function getch() is "used to get a character from console but does not echo to the screen". That is why you do not see them. Consider getchar() instead.
4) [Edit: delete Avoid =-. Thank-you #Daniel Fischer]
5) Your exponential calculation needs rework. Note: your exponent could receive a sign character.
6) When you test if(c=='-'), you do not then fetch another c. You also might want to test for else if(c=='+') and consume that c.
Good luck in your C journey.
49 is the Ascii code for the number 1. So when (0'<=c && c <='9') you need to subtract '0' to get the number itself.
A small hint: 49 is the ASCII for the character 1. You are using getch(), which gives you the return value char.

How to maintain vertical scroll position in a QTableWidget

This a very simple problem to which I can find no solution:
This is my code:
qint32 pos = ui->twShow->verticalScrollBar()->value();
ui->twShow->blockSignals(true);
//Code for updating the contents QTableWidget twShow, this is done by erasing all cells and adding them again, in case it matters.
ui->twShow->blockSignals(false);
if (pos > 0){
ui->twShow->verticalScrollBar()->setValue(pos);
}
What I want to accomplish is simply to maintain the vertical scroll position. However the setValue function ignores the value pos (I've checked by printing the value before and after the instruction and both times its cero).
I have also tried:
QScrollBar *bar = ui->twShow->verticalScrollBar();
// Same code as before
ui->twShow->setVerticalScrollBar(bar); //This line crashes de program
However the last line crashes the program (which I've checked by commenting it, and it works fine).
Any advice would be greatly appreciated...
Thank you very much
QTableWidget * tw;
int desiredRow;
// before update
desiredRow = tw->row(tw->itemAt(1,1));
...
// update code
...
tw->scrollToItem( tw->item( desiredRow, 0),
QAbstractItemView::EnsureVisible | QAbstractItemView::PositionAtTop );
QAbstractItemView::EnsureVisible = 0.
The 'or' flag converts the result to an integer which is not allowed as parameter of the scrollToItem method. On the other hand enums are not intended to be used as combined flags.

Unexpected integer math results on Arduino

I'm trying to smoothly transition an RGB LED from one colour to another. As part of the logic for this I have the following function to determine how big the change will be (it multiplies by a factor f to avoid floating-point math):
int colorDelta(int from, int to, int f) {
int delta;
if (to == from) {
delta = 0;
} else {
delta = (to - from) * f;
}
return delta;
}
When I call colorDelta(0, 255, 1000) I expect the result to be -255000 but instead the function returns 7144.
I've tried performing the operation as directly as possible for debugging, but Serial.print((0 - 255) * 1000, DEC); also writes 7144 to the serial port.
What have I foolishly overlooked here? I'd really like to see the (smoothly transitioning) light. ;)
I would suspect an integer overflow: the int type being incapable of holding -255000. By language standard, signed integer overflow is undefined behavior, but in practice the major bits of a result are usually just thrown away (warning: this observation is not meant to be used in writing code, because undefined behavior remains undefined; it's just for those cases when you have to reason about the program that is known to be wrong).
A good way to check it quickly is computing a difference between your real result and your expected one: -255000 - 7144 = -262144. The latter is -(1<<18), which is the indication that my suspicions are well-founded.

How to append this in Qt?

I want to add a new line in this. This is my sample code:
ui->button->setText(" Tips " + "\n" + TipsCount );
This is the error it shows:
invalid operands of types 'const char [7]' and 'const char [2]' to binary 'operator+'
But when I add to label it gets appended!
ui->label->setText(name + "\n" + City );
Can someone please help me?
This is a very common problem in C++ (in general, not just QT).
Thanks to the magic of operator overloading, name + "\n" gets turned into a method call (couldn't say which one since you don't list the type). In other words, because one of the two things is an object with + overloaded it works.
However when you try to do "abc" + "de", it blows up. The reason is because the compiler attempts to add two arrays together. It doesn't understand that you mean concatenation, and tries to treat it as an arithmetic operation.
To correct this, wrap your string literals in the appropriate string object type (std::string or QString most likely).
Here is a little case study:
QString h = "Hello"; // works
QString w = "World"; // works too, of course
QString a = h + "World"; // works
QString b = "Hello" + w; // also works
QString c = "Hello" + "World"; // does not work
String literals in C++ (text in quotes) are not objects and don't have methods...just like numeric values aren't objects. To make a string start acting "object-like" it has to get wrapped up into an object. QString is one of those wrapping objects, as is the std::string in C++.
Yet the behavior you see in a and b show we're somehow able to add a string literal to an object. That comes from the fact that Qt has defined global operator overloads for both the case where the left operand is a QString with the right a const char*:
http://doc.qt.nokia.com/latest/qstring.html#operator-2b-24
...as well as the other case where the left is a const char* and the right is a QString:
http://doc.qt.nokia.com/latest/qstring.html#operator-2b-27
If those did not exist then you would have had to write:
QString a = h + QString("World");
QString b = QString("Hello") + w;
You could still do that if you want. In that case what you'll cause to run will be the addition overload for both operands as QString:
http://doc.qt.nokia.com/latest/qstring.html#operator-2b-24
But if even that didn't exist, you'd have to call a member function. For instance, append():
http://doc.qt.nokia.com/latest/qstring.html#append
In fact, you might notice that there's no overload for appending an integer to a string. (There's one for a char, however.) So if your TipsCount is an integer, you'll have to find some way of turning it into a QString. The static number() methods are one way.
http://doc.qt.nokia.com/latest/qstring.html#number
So you might find you need:
ui->button->setText(QString(" Tips ") + "\n" + QString::number(TipsCount));

Resources