The QStringParser class provides a variety of methods to process strings of text. If you have a body of text which needs to be separated at a comma or some other delimiter, use the split() method. There are other methods to convert a number to a string, concatenate a list of strings separated by a given delimiter, or replace a marker in some text with a value obtained at run time. This example will show how to use split() and formatArg().
#include <QtCore>
#include <QtGui>
class MainWindow : public QWidget
{
public:
MainWindow();
private:
QLineEdit *textEdit;
QComboBox *split_A;
QComboBox *split_B;
QLineEdit *textFormat;
QLineEdit *arg_1;
QLineEdit *arg_2;
QLineEdit *result;
void parseText();
};
This declaration for MainWindow includes the widget controls which will be updated in the implementation of the parseText() slot method.
MainWindow::MainWindow()
{
setMinimumSize(700, 400);
// part 1
QLabel *textLabel = new QLabel("Enter Text: ");
textEdit = new QLineEdit();
textEdit->setText("A wacky fox and sizeable pig jumped "
"halfway over a blue moon.");
QLabel *label_A1 = new QLabel("split(text, ' ')");
split_A = new QComboBox();
QLabel *label_B1 = new QLabel(
"split(text, \"(fox|pig|blue)\")");
split_B = new QComboBox();
// part 2
QLabel *label_A2 = new QLabel("Enter Text:");
textFormat = new QLineEdit();
textFormat->setText("%1 says hello in example %2");
QLabel *label_B2 = new QLabel("Enter Arg 1:");
arg_1 = new QLineEdit();
arg_1->setText("CopperSpice");
QLabel *label_C2 = new QLabel("Enter Arg 2:");
arg_2 = new QLineEdit();
arg_2->setText("38");
QLabel *label_D2 = new QLabel("formatArg()");
result = new QLineEdit();
QFrame *hline = new QFrame();
hline->setLineWidth(1);
hline->setFrameStyle(QFrame::HLine);
QPushButton *pb_run = new QPushButton();
pb_run->setText("Run QStringParser");
QPushButton *pb_close = new QPushButton();
pb_close->setText("Close");
//
QGridLayout *grid1 = new QGridLayout();
grid1->setHorizontalSpacing(20);
grid1->setVerticalSpacing(15);
grid1->addWidget(textLabel, 3, 1);
grid1->addWidget(textEdit, 3, 2, 1, 2);
grid1->addWidget(label_A1, 4, 2);
grid1->addWidget(split_A, 4, 3, 1, 1);
grid1->addWidget(label_B1, 5, 2);
grid1->addWidget(split_B, 5, 3, 1, 1);
grid1->addWidget(hline, 6, 1, 1, 3);
grid1->addWidget(label_A2, 7, 1);
grid1->addWidget(textFormat, 7, 2, 1, 1);
grid1->addWidget(label_B2, 8, 1);
grid1->addWidget(arg_1, 8, 2, 1, 1);
grid1->addWidget(label_C2, 9, 1);
grid1->addWidget(arg_2, 9, 2, 1, 1);
grid1->addWidget(label_D2, 10, 2);
grid1->addWidget(result, 10, 3, 1, 1);
grid1->addItem(new QSpacerItem(100, 0,
QSizePolicy::Fixed, QSizePolicy::Fixed), 4, 3);
grid1->addItem(new QSpacerItem(0, 0,
QSizePolicy::Expanding, QSizePolicy::Expanding), 13, 3);
QHBoxLayout *layout1 = new QHBoxLayout();
layout1->addStretch();
layout1->addWidget(pb_run);
layout1->addSpacing(20);
layout1->addWidget(pb_close);
layout1->addStretch();
QVBoxLayout *layoutMain = new QVBoxLayout(this);
layoutMain->setContentsMargins(20, 40, 30, 15);
layoutMain->addLayout(grid1);
layoutMain->addLayout(layout1);
connect(pb_run, &QPushButton::clicked,
this, &MainWindow::parseText);
connect(pb_close, &QPushButton::clicked,
this, &QWidget::close);
parseText();
}
There are two parts to this example. The first part shows a textEdit string declared on line 9 with a default sentence which can be modified at run time. Lines 12 and 15 are text labels which indicate how this input text should be parsed. The combo boxes for split_A
and split_B
display the results after calling the QStringParser::split() method.
In the second part a new text string is declared on line 23 with two markers, %1 and %2. The percent sign must be present and there is a limit of 99 different markers in a single body of text. A marker can be repeated any number of times within the text. The values of our text fields arg_1
and arg_2
will be used to replace the markers by QStringParser::formatArg().
– If you modify the textFormat string at run time and remove the %1 marker, the value for arg_1 will be used for the %2 maker. The value for arg_2 will be ignored.
– If you use %1, %2, and %3 no substitution will occur for the last marker and the text “%3” will appear in the output. The original string must be changed in the source code to add a third marker.
After modifying the input text fields, click the “Run QStringParser” push button to update the displayed results.
Signal / Slot Connections
When the Run QStringParser push button is clicked the following slot method will be invoked. The connection is set up on line 95. This method is invoked directly at the end of the constructor to populate the result fields.
void MainWindow::parseText()
{
// part 1
QString text = textEdit->text();
QStringList list = QStringParser::split(text, ' ');
split_A->clear();
split_A->addItems(list);
list = QStringParser::split(text,
QRegularExpression("(fox|pig|blue)",
QPatternOption::CaseInsensitiveOption));
split_B->clear();
split_B->addItems(list);
// part 2
QString str = textFormat->text();
result->setText(str.formatArg(arg_1->text())
.formatArg(arg_2->text()));
}
This block of code is where the QStringParser methods are called to parse the two sample strings. On line 4 the value for textEdit
is retrieved. The call to split() on line 6 returns a list of strings which is created by breaking up the original string after each “space”. The result is added to the combo box split_A on line 8.
On line 10 a regex is used to indicate where the original string should be split apart. The enum on line 12 indicates the regular expression should be case-insensitive, the default is case-sensitive. This result is added to combo box split_B on line 15.
In part two textFormat
is retrieved and the %1 and %2 markers are replaced by the values in arg_1
and arg_2
using the method formatArg().
Main Function
Since the source code for main() has not changed there is no need to show it again. Refer to example 3 or download the full source for this example.
Running the Example
To build and run this example use the same CMake build file and commands as we showed for the first example. The only suggested modification is on line 2 of the CMakeLists.txt file, change “example_1” to “example_38”.