БлогNot. QT: применяем текстовые поля ввода и регулярные выражения

QT: применяем текстовые поля ввода и регулярные выражения

Виджеты-примеры построены на шаблоне QWidget и показывают удобство регулярных выражений при типовой обработке текстовых данных :)

Конечно, "регуляркам" требуется значительно более мощное "железо", чем "вылизанному" коду на ассемблере, но этот фактор сегодня учитывают мало, отдавая предпочтение средам и языкам, позволяющим быструю разработку приложений, пусть даже "тяжёлых". QT именно к таким средам и относится.

1. Проект StringToTemplate показывает "динамическую" проверку вводимой строки на соответствие шаблону (в данном случае, вещественному числу в обычной форме записи). Для работы понадобился единственный пользовательский слот slot1(), обрабатывающий сигнал textChanged() от однострочного поля ввода lineEdit типа QLineEdit. Результат проверки в виде знака "+" или "-" выводится в метку label, вот весь основной код, комментарий поясняет части "регулярки":

void Widget::slot1() {
 QString str = lineEdit->text();
 QString tmpl="^[\\+|\\-]?\\d*([\\.|,]?\\d*)$";
 //^       [\\+|\\-]? \\d*          ([\\.|,]? \\d*)    $
 //начало  знак       цифры         . или ,   цифры    конец
 //строки  числа      целой части             дробной  строки
 //                   части                   части
 QRegExp *q = new QRegExp(tmpl);
 label->setText(q->indexIn(str)!=-1?"+":"-");
}
виджет для проверки формата строки
виджет для проверки формата строки

 Скачать проект QT5 StringToTemplate в архиве .zip (3 Кб)

2. Проект TextEditParsing демонстрирует, как регулярным выражением подсчитать количество слов в многострочном поле, а также с помощью списка строк QStringList list отфильтровать слова от дублей и отсортировать их по алфавиту.

У приложения также единственный слот slot1(), соединённый с сигналом textChanged(), на этот раз получаемым от многострочного текстового поля QTextEdit edit1. Результаты обработки выводятся во второе текстовое поле QTextEdit edit2 с установленным свойством "только для чтения".

Вот основная часть кода:

void Widget::slot1() {
 //Разбить текст из edit1 на слова, вывести их
 //количество и отсортированный список уникальных слов
 //(с точностью до регистра символов)
 QString text = edit1->toPlainText();
  //текст из многострочного поля
 QRegExp reg("[\\s|\\n|\\r|\\.|,|!|\\?|:|;]+");
  //символы, считающиеся границами слов
 QStringList list =
  text.split(reg, QString::SkipEmptyParts);
  //разбить строку на слова, пропуская пустые
 int cnt = list.count();
 QString newtext = QString("Всего слов: ")+
                   QString::number(cnt)+"\n";
 list.removeDuplicates(); //Удалить дубли из списка
 list.sort(Qt::CaseInsensitive); //Отсортировать
 foreach (const QString &str, list) {
  newtext += str+"\n"; //Составить список по алфавиту
 }
 edit2->setText(newtext);
}
виджет для работы со списком слов из текста
виджет для работы со списком слов из текста

 Скачать проект QT5 TextEditParsing в архиве .zip (3 Кб)

3. Заметим также, что для ограничения ввода в текстовые поля нерационально использовать обработку событий, а лучше валидаторы с регулярным выражением. Так, чтобы разрешить ввод в текстовое поле QLineEdit только целого числа с необязательным лидирующим знаком "-" или "+", достаточно в заголовочном файле виджета заинклудить

#include <QValidator>

а в его конструкторе после ui->setupUi(this); написать

QRegExp RegExp("[\\+\\-]?\\d+");
QValidator *Validator = new QRegExpValidator(RegExp, this);
ui->lineEdit->setValidator(Validator);

Для того, чтобы вводить в QLineEdit, например, только допустимый IP-адрес, применим аналогичный подход:

QString ipItem = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])";
QRegExp RegExp ("^" + ipItem + "\\." + ipItem + "\\." + ipItem + "\\." + ipItem + "$");

И далее создаём и применяем валидатор с регулярным выражением RegExp. Ну и любой другой ввод по шаблону реализуется так же, учите Regexp'ы :)

P.S. В Qt6 нет QRegExp, его нужно заменять на QRegularExpression, так что придётся указать

#include <QRegularExpression>

в файле widget.h и изменить код слота slot1 таким образом:

void Widget::slot1() {
 QString str = lineEdit->text();
 QString tmpl="^[\\+|\\-]?\\d*([\\.|,]?\\d*)$";
 QRegularExpression q (tmpl);
 QRegularExpressionMatch match = q.match(str);
 bool hasMatch = match.hasMatch();
 label->setText(hasMatch==true?"+":"-");
}

В отдельных случаях помогает указание

QT += core5compat

в файле проекта .pro.

17.02.2017, 19:51 [21129 просмотров]


теги: textprocessing c++ программирование учебное список qt

показать комментарии (1)