Создание своего терминала на C++ и Qt: Часть 1

от автора

Привет, хабр! Сегодня мы создадим свой собственный терминал на языке программирования C++. Я являюсь фанатом Linux, и пользуюсь минималистичными терминальными программами — от Vim как IDE до чатов. Есть множество терминалов, у каждого из них есть плюсы и минусы. Наш терминал не будет претендовать на место серьезного проекта, но если вы хотите улучшить код, который мы сегодня напишем — то вы молодцы, можете без проблем развить наш терминал.

Это будет небольшой, минималистичный терминал для Linux. Он будет на основе фреймворка Qt 5 и библиотеки qtermwidget5

Не буду долго тянуть, вперед! Исходный код будет в моем репозитории.

Что нам сегодня будет нужно:

  • Компилятор gcc (G++)

  • Make, QMake

  • Qt5-base

  • qtermwidget5

  • build‑devel/essential


Итак, для начала нам нужно установить все зависимости, которые я привел сверху.

# Arch sudo pacman -Sy qtermwidget basedevel qt5-base make gcc # Для других дистрибутивов смотрите в их репозиториях

Основа нашего терминала — Qt-виджет qtermwidget.

Работающий минимум

Для начала создаем проект:

qmake -project

После в файл <названиеПроекта>.pro помещаем следующий код (не забудьте заменить имена):

###################################################################### # Automatically generated by qmake (3.1) Mon Nov 27 18:10:42 2023 ######################################################################  TEMPLATE = app TARGET = НАЗВАНИЕ INCLUDEPATH += . INCLUDEPATH += /usr/include/qtermwidget5  # You can make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # Please consult the documentation of the deprecated API in order to know # how to port your code away from it. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0  # Input SOURCES += src/исходныйКод.cpp TEMPLATE += app QT += gui widgets unix:!macx: LIBS += -lqtermwidget5 

Дальше при помощи qmake мы создаем Makefile:

qmake -makefile

И здесь мы создаем файл кода С++ и пишем в него следующее:

#include <QApplication> #include <QMainWindow>  #include "qtermwidget.h"  int main(int argc, char *argv[]) {   // Создаем окно и приложение   QApplication app(argc, argv);   QMainWindow *mainWindow = new QMainWindow();    // Создаем объект консоли   QTermWidget *console = new QTermWidget();    // Добавляем шрифт терминала   QFont font = QApplication::font();   font.setFamily("Monospace"); // задаем шрифт monospace   font.setPointSize(14); // задаем размер шрифта в pt    console->setTerminalFont(font); // задаем наши характеристики шрифта в консоль    // Показ окна   QObject::connect(console, SIGNAL(finished()), mainWindow, SLOT(close()));   mainWindow->setCentralWidget(console);   mainWindow->show();    return app.exec(); } 

Мы включаем нужные нам библиотеки, создаем приложение и создаем виджет терминала. После мы задаем ему шрифт. В конце подключаем терминал и главное окно (то есть закрытие одного окна/виджета заставит закрыться другое окно/виджет), а после показываем окно.

Компиляция

На протяжении всего туториала — компиляция будет состоять из одной строчки:

make

Цветовые схемы

Добавим немного цветов в наш терминал.

#include <QApplication> #include <QMainWindow>  #include "qtermwidget.h"  int main(int argc, char *argv[]) {   // Создаем окно и приложение   QApplication app(argc, argv);   QMainWindow *mainWindow = new QMainWindow();    // Создаем объект консоли   QTermWidget *console = new QTermWidget();    // Добавляем шрифт терминала   QFont font = QApplication::font();   font.setFamily("Monospace"); // задаем шрифт monospace   font.setPointSize(14); // задаем размер шрифта в pt    console->setTerminalFont(font); // задаем наши характеристики шрифта в консоль    // Задаем цветовую схему. Существующие можно посмотреть в /usr/share/qtermwidget5/color-schemes   console->setColorScheme("Tango");    // Показ окна   QObject::connect(console, SIGNAL(finished()), mainWindow, SLOT(close()));   mainWindow->setCentralWidget(console);   mainWindow->show();    return app.exec(); } 

Мы добавляем в наш предыдущий код всего одну функцию — console->setColorScheme("Tango");

Эта волшебная функция заставляет принять наш терминал цветовую схему Tango (остальные можно посмотреть в /usr/share/qtermwidget5/color‑schemes/

Копипаста!

Что‑же за терминал такой, в котором даже не работает копирование и вставка текста? Давайте это исправим. Мы добавим кейбинды!

#include <QApplication> #include <QMainWindow> #include <QKeySequence> // добавляем новую библиотеку #include "qtermwidget.h"  int main(int argc, char *argv[]) {   // Создаем окно и приложение   QApplication app(argc, argv);   QMainWindow *mainWindow = new QMainWindow();    // Создаем объект консоли   QTermWidget *console = new QTermWidget();    // Добавляем шрифт терминала   QFont font = QApplication::font();   font.setFamily("Monospace"); // задаем шрифт monospace   font.setPointSize(14); // задаем размер шрифта в pt    console->setTerminalFont(font); // задаем наши характеристики шрифта в консоль    // Задаем цветовую схему. Существующие можно посмотреть в /usr/share/qtermwidget5/color-schemes   console->setColorScheme("Tango");    // Подключаем   QObject::connect(console, &QTermWidget::termKeyPressed, mainWindow, [=](const QKeyEvent *key) -> void { // проверяем нажатия клавиш if (key->matches(QKeySequence::Copy)) { console->copyClipboard(); // ctrl+c } });    // Показ окна   QObject::connect(console, SIGNAL(finished()), mainWindow, SLOT(close()));   mainWindow->setCentralWidget(console);   mainWindow->show();    return app.exec(); } 

Мы получаем нажатия клавиш, и если они равны ctrl+c (копирование) или ctrl+v (вставка) мы копируем или вставляем текст. Но есть интересная фича — если мы сделаем кейбинд вставки текста, то текст будет вставляться два раза. Поэтому мы не пишем кейбинд, т.к. вставка текста работвет по умолчанию, в отличии от копирования.

Ссылки, ссылки, ссылки…

Давайте создадим еще несколько «плюшек» — возможность активации ссылок, моргающий курсор и внутренние отступы!

#include <QApplication> #include <QMainWindow> #include <QDesktopServices> // добавляем новую библиотеку #include <QKeySequence> #include "qtermwidget.h"  void activateLink(const QUrl &url, bool fromContextMenu) {   /* Функция, которая ничего не возвращает, принимает на вход URL и    fromContextMenu.   Открывает ссылку в доступном браузере */   if (QApplication::keyboardModifiers() & Qt::ControlModifier ||         fromContextMenu) {     QDesktopServices::openUrl(url);   } }  int main(int argc, char *argv[]) {   // Создаем окно и приложение   QApplication app(argc, argv);   QMainWindow *mainWindow = new QMainWindow();    // Создаем объект консоли   QTermWidget *console = new QTermWidget();    // Добавляем шрифт терминала   QFont font = QApplication::font();   font.setFamily("Monospace"); // задаем шрифт monospace   font.setPointSize(14); // задаем размер шрифта в pt    console->setTerminalFont(font); // задаем наши характеристики шрифта в консоль   console->setBlinkingCursor(true); // мерцающий курсор   // Добавляем внутренние отступы 10 пикселей   console->setMargin(10);    // Задаем цветовую схему. Существующие можно посмотреть в /usr/share/qtermwidget5/color-schemes   console->setColorScheme("Tango");    // Подключаем   QObject::connect(console, &QTermWidget::termKeyPressed, mainWindow, [=](const QKeyEvent *key) -> void { // проверяем нажатия клавиш if (key->matches(QKeySequence::Copy)) { console->copyClipboard(); // ctrl+c } });   // Подключаем функцию активации ссылки   QObject::connect(console, &QTermWidget::urlActivated, mainWindow, activateLink);      // Показ окна   QObject::connect(console, SIGNAL(finished()), mainWindow, SLOT(close()));   mainWindow->setCentralWidget(console);   mainWindow->show();    return app.exec(); } 

И компилируя мы получаем…

Вот такой у нас получился терминал. Я использую на скриншотах шрифт не Monospace, а Iosevka Nerd Fonts.

Заключение

В этой части мы реализовали базовые возможности нашего терминала. В следующей части мы создадим больше плюшек — подумаем над созданием конфигуратора, добавим больше функций.

Спасибо за прочтение! Надеюсь вам понравилось!


ссылка на оригинал статьи https://habr.com/ru/articles/776716/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *