Get (X,Y) position of the Text in QLabel - qt

How to get the starting position of text in the QLabel.
Ex:
How can i get the Left Top position of the text displayed in the QLabel(only) without overriding the paintEvent.
I dont have permission to override paintEvent or use other widgets like QLineEdit
I can get the Width/Height using fontmetrics but to get X,Y for the text?

you can use below code :
QFontMetrics fm(ui->label->font());
int textWide = fm.horizontalAdvance(ui->label->text());
int textHeight = fm.height();
int textX , textY;
if ((ui->label->alignment() & Qt::AlignLeft) == Qt::AlignLeft)
textX = ui->label->x();
if ((ui->label->alignment() & Qt::AlignHCenter) == Qt::AlignHCenter)
textX = ui->label->x() + ( ui->label->width() - textWide) / 2;
if ((ui->label->alignment() & Qt::AlignRight) == Qt::AlignRight)
textX = ui->label->x() + ui->label->width() - textWide ;
if ((ui->label->alignment() & Qt::AlignTop) == Qt::AlignTop)
textY = ui->label->y();
if ((ui->label->alignment() & Qt::AlignVCenter) == Qt::AlignVCenter)
textY = ui->label->y() + ( ui->label->height() - textHeight) / 2;
if ((ui->label->alignment() & Qt::AlignBottom) == Qt::AlignBottom)
textY = ui->label->y() + ui->label->height() - textHeight;
qDebug() << textX << textY << ui->label->x() << ui->label->y();

Related

How can I simplify this OpenCL Kernel code?

void write_solution(uchar our_index[16], global uchar *solution) {
uchar8 solution_data = 0;
solution_data.s0 = (our_index[0] & 0xF) + ((our_index[1] & 0xF) << 4);
solution_data.s1 = (our_index[2] & 0xF) + ((our_index[3] & 0xF) << 4);
solution_data.s2 = (our_index[4] & 0xF) + ((our_index[5] & 0xF) << 4);
solution_data.s3 = (our_index[6] & 0xF) + ((our_index[7] & 0xF) << 4);
solution_data.s4 = (our_index[8] & 0xF) + ((our_index[9] & 0xF) << 4);
solution_data.s5 = (our_index[10] & 0xF) + ((our_index[11] & 0xF) << 4);
solution_data.s6 = (our_index[12] & 0xF) + ((our_index[13] & 0xF) << 4);
solution_data.s7 = (our_index[14] & 0xF) + ((our_index[15] & 0xF) << 4);
vstore8(solution_data, 0, solution);
}
As can be seen in the code, it would be really lovely if I could just write it like this instead:
void write_solution(uchar our_index[16], global uchar *solution) {
uchar8 solution_data = 0;
for(int i = 0; i < 8; i++) {
solution_data[i] = (our_index[i * 2] & 0xF) + ((our_index[i * 2 + 1] & 0xF) << 4);
}
vstore8(solution_data, 0, solution);
}
But of course, OpenCL doesn't allow the indexed notation described in the above code to be used with vector types.
Is there anything I can do to solve this issue?
Vector operations are component-wise, and you can take advantage of the .even and .odd vector addressing modes. Does this work for you?
void write_solution(uchar16 our_index, global uchar *solution) {
uchar8 solution_data = 0;
solution_data = (our_index.even & 0xF) + ((our_index.odd & 0xF) << 4);
vstore8(solution_data, 0, solution);
}

How to show a floating number with a fixed amount of digits in Qt?

I want to display a floating number in Qt with a fixed amount of digits (4), but without filling non-used digits with zero (the equivalent of having a maximum number of digits). In other words, this is what I want to show for the following examples:
0 -> 0.0
10 -> 10.0
980.5 -> 980.5
1200.5 -> 1.200 k
9900.9 -> 9.900 k
120500.9 -> 120.5 k
999888.88 -> 999.9 k
etc.. I tried many combinations of both QString::number() as well as QString::args(), without success. So how can I do that?
Note: I'm aware that for numbers higher then 1000, I'll have to apply a division and add the label 'k' manually - I'm already doing that.
EDIT:
The following code does exactly what I want, only that it is quite inappropriate with all those if else. I would like to know how can I do that with Qt's functions:
float temp = getSomeValue();
const char* itemUnities[] = { "V", "W", "A", "J" };
if (temp < 10.0f)
{
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',3));
painter.drawText(defaultX + 110,yPosition,tr(itemUnities[aaa]));
}
else if (temp < 100.0f)
{
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',2));
painter.drawText(defaultX + 110,yPosition,tr(itemUnities[aaa]));
}
else if (temp < 1000.0f)
{
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',1));
painter.drawText(defaultX + 110,yPosition,tr(itemUnities[aaa]));
}
else if (temp < 10000.0f)
{
temp *= 0.001;
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',3));
painter.drawText(defaultX + 110,yPosition,tr("k") + tr(itemUnities[aaa]));
}
else if (temp < 100000.0f)
{
temp *= 0.001;
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',2));
painter.drawText(defaultX + 110,yPosition,tr("k") + tr(itemUnities[aaa]));
}
else if (temp < 1000000.0f)
{
temp *= 0.001;
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',1));
painter.drawText(defaultX + 110,yPosition,tr("k") + tr(itemUnities[aaa]));
}
else if (temp < 10000000.0f)
{
temp *= 0.000001;
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',3));
painter.drawText(defaultX + 110,yPosition,tr("M") + tr(itemUnities[aaa]));
}
else if (temp < 100000000.0f)
{
temp *= 0.000001;
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',2));
painter.drawText(defaultX + 110,yPosition,tr("M") + tr(itemUnities[aaa]));
}
else if (temp < 1000000000.0f)
{
temp *= 0.000001;
painter.drawText(defaultX + 60,yPosition,QString::number(temp,'f',1));
painter.drawText(defaultX + 110,yPosition,tr("M") + tr(itemUnities[aaa]));
}
Since you have very specific wishes for the conversion, a built in method does not provide all the functionality, but with some tricks, you can use QString::number() and QString::truncate():
QString doubleToQStr(const double val, const size_t d)
{
QString str = QString::number(val,'g',15);
if( val >= std::pow(10.0,static_cast<double>(d-1)) )
{
str.truncate(d);
// find magnitude
size_t mag = 0;
while( val >= std::pow( 10.0, static_cast<double>(mag) ) ) { mag++; }
if ( mag > 3 )
{
size_t dotpos = mag % 3;
str.insert(dotpos,".");
size_t mag3 = mag - dotpos;
switch( mag3 )
{
case 3:
str += " k"; break;
case 6:
str += " M"; break;
case 9:
str += " G"; break;
case 12:
str += " T"; break;
default:
str += " ?"; break;
}
}
}
else if ( val < std::pow(10.0,static_cast<double>(-(static_cast<int>(d)-1))) )
{ str = "0.0"; }
else
{ str.truncate(d+1); }
return str;
}
Here are the test cases I used:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
std::cout << "99919999.9 -> " << doubleToQStr(99919999.9, 4).toStdString() << std::endl;
std::cout << "9999.9 -> " << doubleToQStr(9999.9, 4).toStdString() << std::endl;
std::cout << "999.9 -> " << doubleToQStr(999.9, 4).toStdString() << std::endl;
std::cout << "99.9 -> " << doubleToQStr(99.9, 4).toStdString() << std::endl;
std::cout << "9.9 -> " << doubleToQStr(9.9, 4).toStdString() << std::endl;
std::cout << "0.9 -> " << doubleToQStr(0.9, 4).toStdString() << std::endl;
std::cout << "0.09 -> " << doubleToQStr(0.09, 4).toStdString() << std::endl;
std::cout << "0.009 -> " << doubleToQStr(0.009, 4).toStdString() << std::endl;
std::cout << "0.0009 -> " << doubleToQStr(0.0009, 4).toStdString() << std::endl;
std::cout << "0.00009 -> " << doubleToQStr(0.00009, 4).toStdString() << std::endl;
return a.exec();
}

Strtol implementation different behaviour on 32 and 64 bit machine

#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <tgmath.h>
#include <limits.h>
#include <stdbool.h>
#include <errno.h>
#define NEGATIVE -1
#define POSITIVE 1
#define OCTAL 8
#define DECIMAL 10
#define HEXADECIMAL 16
#define BASE_MIN 2
#define BASE_MAX 36
long int strtol (const char * str, char ** endPtr, int base)
{
if(base < 0 || base == 1 || base > BASE_MAX)
{
errno = EINVAL;
return 0L;
}
else
{
bool conversion = true;
int i = 0, sign = POSITIVE, save;
while(isspace(*(str + i)))
i++;
if(*(str + i) == '\0')
{
conversion = false;
save = i;
}
if(*(str + i) == '-')
{
sign = NEGATIVE;
i++;
}
else if(*(str + i) == '+')
i++;
if(base == 0) // find out base
{
if(*(str + i) == '0')
{
if(toupper(*(str + i + 1)) == 'X')
{
base = HEXADECIMAL;
i++;
}
else
base = OCTAL;
i++;
}
else
base = DECIMAL;
}
else if(base == OCTAL)
{
if(*(str + i) == '0')
i++;
}
else if(base == HEXADECIMAL)
{
if(*(str + i) == '0')
if(*(str + i + 1) == 'x' || *(str + i + 1) == 'X')
i += 2;
}
int start = i, end, exp, check = i;
long int long_int, sum, multiplier;
if(conversion) // find out the correct part of the string corresponding to the number
{
if(base < DECIMAL)
{
while(*(str + i) >= '0' && *(str + i) < base + '0') // numbers from 0 to base - 1
i++;
}
else if(base == DECIMAL)
{
while(*(str + i) >= '0' && *(str + i) <= '9') // numbers from 0 to 9
i++;
}
else
{
while((*(str + i) >= '0' && *(str + i) <= '9') || (toupper(*(str + i)) >= 'A' && toupper(*(str + i)) < 'A' + base - 10))
i++;// numbers from 0 to 9 and uper and lowercase letters from a to a + base - 11
}
}
if(i == check && conversion) //no digits at all
{
conversion = false;
save = i;
}
else if(endPtr != NULL && conversion) // assign pointer
*endPtr = (char *) (str + i);
if(conversion)
{
for(end = i - 1, exp = 0, long_int = 0L; end >= start; end--, exp++)
{
multiplier = pow(base, exp);
sum = 0L;
if(*(str + end) >= '0' && *(str + end) <= '9')
sum = (*(str + end) - '0') * multiplier;
else if(*(str + end) >= 'A' && *(str + i) <= (base == BASE_MAX ? 'Z' : 'F'))
sum = (*(str + end) - 'A' + 10) * multiplier;
else if(*(str + end) >= 'a' && *(str + i) <= (base == BASE_MAX ? 'z' : 'f'))
sum = (*(str + end) - 'a' + 10) * multiplier;
if(long_int <= LONG_MIN + sum)
{
errno = ERANGE;
return LONG_MIN;
}
if(long_int >= LONG_MAX - sum)
{
errno = ERANGE;
return LONG_MAX;
}
else
long_int += sum;
}
return sign * long_int;
}
else
{
if(endPtr != NULL)
{// if base is 16 we check if the string given is not in the form 0xIncorrect string in that way we need to return xIncorrect part of the string
if(base == HEXADECIMAL && save >= 2 && toupper(*(str + save - 1)) == 'X' && *(str + save - 2) == '0')
*endPtr = (char *) str + save - 1;
else if(base == OCTAL && save >= 1 && *(str + save - 1) == '0')
*endPtr = (char *) str + save;// if the string is of base 8 and in the form 0incorrect string
else //then we return everything after the 0 as the endptr string
*endPtr = (char *) str;//in other cases no conversion was done so we return original pointer
}
return 0L;
}
}
}
I've got problem with writing implementation of strtol() function. The thing is i compiled it on 64 bit machine and the output was correct but today i checked it on another machine that is 32-bit and something got wrong. 32-bit machine showed the result that for example string "7FFFFFFF" is out of range when on 64-bits the results is that strtol succeded which is the same as for th standard function. I also checked errno value and for 32-bit machine it's set to ERANGE which shouldn't be and it's not not on 64-bit. I have program that checks if your implementation gives the same output as the standard one for different strings. I spent few hours looking for possible bug but i'm out of ideas? Any tips?

Convert Int value to CSS Color (to use with QML Canvas)

I have a colour value stored as an integer that I get from native code.
Is there a way I can use this value directly without having to separate each invididual RGB component with something like this?
var color_val = GetColourFromNativeCode();
var red = (color_val>> 16) & 0xFF;
var green = (color_val>> 8) & 0xFF;
var blue = color_val & 0xFF;
context.strokeStyle = "rgb(" + red + "," + green + "," + blue + ")";
Even simpler : use the Qt.rgba () method :
context.strokeStyle = Qt.rgba ((color_val >> 16 & 0xFF) / 255,
(color_val >> 8 & 0xFF) / 255,
(color_val & 0xFF) / 255);
That way, Qt engine converts it to an actual 'color' typed variable.

Qt keeping mouse centered

I'm wondering if anyone has a trick to keep the mouse position centered in a (QGL)widget for Qt. I read that one could set the mouseposition after finding the delta, but this way works very buggy for me. Mouse events are not properly registered, any if they do, very jumpy.
void World::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
GLfloat dx = GLfloat(event->x() - lastPos.x()) / width();
GLfloat dy = GLfloat(event->y() - lastPos.y()) / height();
player->rotHorizontal += 360.0 * dx;
if(player->rotHorizontal < 0.0)
player->rotHorizontal += 360.0;
else if(player->rotHorizontal > +360.0)
player->rotHorizontal -= 360.0;
player->rotVertical += 360.0 * dy;
if (player->rotVertical > MAX_ROTATION_UP) {
player->rotVertical = MAX_ROTATION_UP;
} else if (player->rotVertical < -MAX_ROTATION_UP) {
player->rotVertical = -MAX_ROTATION_UP;
}
}
// int diffX = event->pos().x() - lastPos.x() % 20;
// int diffY = event->pos().y() - lastPos.y() % 20;
// if (diffY > 10 || diffX > 10 || diffY < -10 || diffX < -10) {
// QPoint glob = mapToGlobal(QPoint(this->pos().x() + width()/2, this->pos().y() + height()/2));
// QCursor::setPos(glob);
// }
lastPos = event->pos();
QGLWidget::mouseMoveEvent(event);
}
I commented out the code which would keep the mouse centered. If this would work, I would place it in the leftclick area.
Fixed:
void World::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
GLfloat dx = GLfloat(event->x() - lastPos.x()) / width();
GLfloat dy = GLfloat(event->y() - lastPos.y()) / height();
player->rotHorizontal += 360.0 * dx;
if(player->rotHorizontal < 0.0)
player->rotHorizontal += 360.0;
else if(player->rotHorizontal > +360.0)
player->rotHorizontal -= 360.0;
player->rotVertical += 360.0 * dy;
if (player->rotVertical > MAX_ROTATION_UP) {
player->rotVertical = MAX_ROTATION_UP;
} else if (player->rotVertical < -MAX_ROTATION_UP) {
player->rotVertical = -MAX_ROTATION_UP;
}
}
QPoint glob = mapToGlobal(QPoint(width()/2,height()/2));
QCursor::setPos(glob);
lastPos = QPoint(width()/2,height()/2);
QGLWidget::mouseMoveEvent(event);
}

Resources