QT: простой виджет "суммирование стека чисел"
Сделаем виджет как в этой заметке, если в Вашем QT появились какие-то дополнительные шаги при создании проекта - оставляем выбор по умолчанию, нажимая кнопку "Далее".
Здесь сознательно не использовано назначение одного обработчика нескольким кнопкам, программное создание массива кнопок и т.п. приёмы из этой статьи, код максимально облегчен.
По нажатию кнопки "+" добавляем в стек то, что определяется как число в поле ввода, по "-" удаляем, по "=" суммируем числа из стека, по "C" очищаем стек.
Также код показывает следующие типовые моменты:
- логическое создание несложного интерфейса "по строкам" сетки
QGridLayout
; - типовые настройки окна виджета, включая позиционирование по центру основного экрана.
Для этого виджету по-прежнему нужно передавать ссылку на экземпляр родительского приложения
QApplication
(у насparent
), но часто применяемый способ центрированияparent->desktop()->availableGeometry()
согласно документации по новым версиям, устарел, и теперь нужно
parent->screens().first()->geometry()
- базовое преобразование строки
QString
в вещественное число и вещественного числа в строкуQString
; - программное добавление сигналов и слотов, в том числе, обработка двух разных сигналов одним слотом (элемент в стек можно добавлять как кнопкой "+", так и нажатием Enter в поле ввода);
- поддержка списка строк в
QTextEdit
без лёгких в написании, но трудоёмких при расчётах операций по преобразованиюQTextEdit
вQStringList
и обратно, как здесь; - хотя мы поддерживаем "стекоподобную" функциональность, использовать именно
QStack
с его методами, автоматически удаляющими элементы при извлечении, незачем, обычныйQVector
гораздо удобнее; - с другой стороны, платой за отсутствие списка служит необходимость удалять "вручную"
последнюю строку из
QTextEdit
, это делает методremoveLastLineFromQTextEdit
, которому передаётся указатель наQTextEdit
, чтобы метод можно было применять отдельно от класса. В реальности наши данные всё равно хранятся в векторе и текстовое поле служит лишь для иллюстрации. "Вытащить" изQVector stack
все строки мы могли и простымQList <QString> ql = stack.toList();
а объединить потом обратно и заменить содержимое
QTextEdit stackList
столь же лёгкимQString qs = ql.join('\n'); stackList->clear(); stackList->append(qs);
Ниже прикреплены скриншот приложения и архив с проектом.

скриншот приложения в работе
Скачать этот проект QT 5.10+ в архиве .zip, папка уже создана внутри архива (3 Кб)
В качестве дополнения научим виджет реагировать на события Windows (нажатия клавиш и перемещение мыши), для этого добавим прототипы соответствующих методов в класс виджета:
protected: virtual void keyReleaseEvent(QKeyEvent *event); virtual void mousePressEvent (QMouseEvent *); virtual void mouseMoveEvent (QMouseEvent *);
В конструкторе виджета предусмотрим слежение за перемещением мыши (по умолчанию отслеживаются только нажатия кнопок):
setMouseTracking (true);
Обработчик нажатия клавиш будет получать их коды, обрабатывая только те, что дублируют действие кнопок виджета.
void Widget::keyReleaseEvent(QKeyEvent *event) { int key=event->key(); //целочисленный код клавиши switch (key) { case Qt::Key_Plus: event->ignore(); //Отменить дальнейшую обработку события this->deleteLastChar(displaystring); //Удалить завешающий символ из QLineEdit this->b1Clicked(); //Вызвать слот-обработчик соответствующнй кнопки break; case Qt::Key_Minus: event->ignore(); this->deleteLastChar(displaystring); this->b2Clicked(); break; case Qt::Key_Escape: event->ignore(); this->deleteLastChar(displaystring); this->b3Clicked(); break; case Qt::Key_Equal: event->ignore(); this->deleteLastChar(displaystring); this->b4Clicked(); break; default: //Здесь можно обрабатывать другие коды клавиш break; } }
Метод для удаления последнего символа из QLineEdit
пришлось написать отдельно, по умолчанию стандартный виджет просто так не "отдаст" своего символа.
void Widget::deleteLastChar (QLineEdit *q) { int len = q->text().length(); q->setCursorPosition(len -1); q->setText(q->text().remove(len - 1,1)); }
Обработчик событий от мыши будет просто выводить текущие координаты курсора в строке заголовка окна виджета.
void Widget::mousePressEvent(QMouseEvent *event) { //клик мышью //if (event->button()==Qt::LeftButton) { //Какая кнопка мыши нажата QPoint position = event->pos(); //Позиция нажатия int pos = this->windowTitle().indexOf(':'); QString title = pos > -1 ? this->windowTitle().remove(pos,this->windowTitle().size() - pos) : this->windowTitle(); this->setWindowTitle (title + ": " + QString::number(position.x())+","+QString::number(position.y())); //} } void Widget::mouseMoveEvent(QMouseEvent *event) { //перемещение курсора this->mousePressEvent(event); }
Мы получили небольшое приложение, иллюстрирующее основные возможности по разработке несложных виджетов.
Скачать этот проект QT 5.10+ в архиве .zip, папка уже создана внутри архива (4 Кб)
13.02.2021, 14:11; рейтинг: 45