PDA

View Full Version : Get hex from Qlineedit and send to serial port



hovuquocan1997
27th July 2015, 02:31
Hello everyone, my question is how to get hex pairs from Qlineedit and send them to serial port
I know how to use Qvalidator to restrain users from inputting anything else besides, but I don't know how to get those values and set them as chars to send to serial port. For example, the user will input 01 02 03 04 05, and through a pushButton, I want my program to get those values in pair, then create a char array that's basically like this
{0x01, 0x02, 0x03, 0x04, 0x05} so that I can send it to the serial port. I will appreciate any help, thank you :)

anda_skoa
27th July 2015, 10:31
QString::toInt() using 16 as the base.
Then taking the lowest byte of the int.

Cheers,
_

hovuquocan1997
27th July 2015, 16:51
Thank you for the reply, here is what I have so far and it's still not working,


void MainWindow::on_pushButton_3_clicked() //testing button
{
ui->lineEdit_2->setInputMask("hhhhhhhhhhhhhh");
QString input = ui->lineEdit_2->text();
bool ok;
char command=input.toInt(&ok,16);
serial->write(command,sizeof(command));
}


and also is there a method to input as many as hex pairs as I want? Since setinputmask restricts my input to only that many that I set. Thank you.

anda_skoa
27th July 2015, 20:26
Well, if you line edit has multiple tuples, you need to first separate them before calling toInt().
See QString::mid().

Instead of the mask you could try a validator, maybe a QRegularExpressionValidator or a custom one.

Cheers,
_

hovuquocan1997
27th July 2015, 22:24
Can you please provide an example of QRegularExpressionValidator? I don't know how to use it even after reading the class page.

jefftee
28th July 2015, 00:34
There are a ton of examples on the class page itself. You use it like any of the other validator classes but in the case of QRegularExpressionValidator, it uses a QRegularExpression to validate the input.

Here's a quick example of a QRegularExpression that accepts a list of one or two digit hex values (0-9 or A-F) separated by a comma:



QRegularExpression regex("^(?:(?:[0-9A-F]{1,2})(?:,[0-9A-F]{1,2})*)$");


Use that to validate your QTextInput, then split into individual values using QString::split(","), etc. The regex explanation is:


^ assert position at start of a line
(?:(?:[0-9A-F]{1,2})(?:,[0-9A-F]{1,2})*) Non-capturing group
(?:[0-9A-F]{1,2}) Non-capturing group
[0-9A-F]{1,2} match a single character present in the list below
Quantifier: {1,2} Between 1 and 2 times, as many times as possible, giving back as needed [greedy]
0-9 a single character in the range between 0 and 9
A-F a single character in the range between A and F (case sensitive)
(?:,[0-9A-F]{1,2})* Non-capturing group
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
, matches the character , literally
[0-9A-F]{1,2} match a single character present in the list below
Quantifier: {1,2} Between 1 and 2 times, as many times as possible, giving back as needed [greedy]
0-9 a single character in the range between 0 and 9
A-F a single character in the range between A and F (case sensitive)
$ assert position at end of a line
g modifier: global. All matches (don't return on first match)
m modifier: multi-line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)

hovuquocan1997
29th July 2015, 15:42
Thank you for your help, but after I split them into a list, how do I access each element in the list and convert them to char values?

jefftee
29th July 2015, 16:18
You need to read the doc for QStringList, which is the type returned from QString::split.

hovuquocan1997
29th July 2015, 17:01
So my lineedit is named "data", and the pushButton is named "sendData", here is the code I have:


void MainWindow::on_sendData_clicked()
{
QString input = ui->data->text();
QStringList list1 = input.split(",");
int size = list1.size();
char senddata[size];
for (int i=0; i <= size; i++){
QString ran = list1 [i];
bool ok;
senddata[i]=ran.toInt(&ok,16);
}
serial->write(senddata,sizeof(senddata));
}

I thought it would work okay, but somehow I can't initialize the char array "senddata" without an actual size, do you have any fix for that? Thank you.

jefftee
29th July 2015, 17:59
I thought it would work okay, but somehow I can't initialize the char array "senddata" without an actual size, do you have any fix for that? Thank you.
Your for loop should test i < size, not <=. As written, you're looping one too many times, exceeding the size of both the QStringList list1 and the char array senddata.

Once you fix the for loop, you should make it easy on yourself and use a QByteArray for senddata. It allows a variable length array of bytes, access to individual bytes using array syntax, and you can access the data itself using QByteArray::constData and the size of the data with QByteArray::length.

hovuquocan1997
29th July 2015, 18:07
I've tried QByteArray also, but the same problem persists, the problem is not about the type but about the size of the array. Two of the errors are "senddata: unknown size" and "cannot allocate an array of constant size 0" on this line
char senddata[size];
and even when I switched to QByteArray, the same errors pop up.

jefftee
29th July 2015, 18:17
You don't need to specify the size of the byte array if you use QByteArray, that was my whole point. Here is your code using QByteArray and proper for loop bounds:



QString input = ui->data->text();
QStringList list1 = input.split(",");
int size = list1.size();
QByteArray senddata;
for (int i=0; i < size; i++){
QString ran = list1 [i];
bool ok;
senddata[i]=ran.toInt(&ok,16);
}

serial->write(senddata.constData(), senddata.length());

hovuquocan1997
29th July 2015, 18:44
Thank you very much, that solved everything! Thanks for helping me so much, I really appreciate it!