
IscanderChe
IscanderChe
- 0
- 0

C++ → Простой текстовый редактор на Ultimate++
C++, U++, Ultimate++, UPP
Об Ultimate++ ( https://www.ultimatepp.org/ ) я узнал совершенно случайно, когда прочитал в айтишной новостной RSS-ленте об очередном обновлении этого фреймворка. Что ж, подумал я, раз мои пен-проекты пока в заторможенном состоянии, почему бы не попробовать что-то новое.
Ultimate++ (сокращённо U++ или UPP) представляет собой кроссплатформенный фреймворк для разработки GUI-приложений на основе C++. Кроме кода самого фреймворка в состав входит собственный сборщик BLITZ и среда разработки TheIDE для редактирования кода и элементов GUI.
Попробуем написать простейший блокнот на основе U++.

Дневники разработки → Проект DBComponents. Часть 1. Требования к проекту и базе данных
DBComponents, Qt, Iscander Che, C++
Требования к проекту
Проект реализует базу данных IT-компонентов. Планируется пока три категории: мониторы, медицинские принтеры, системные блоки. Также в функционал базы входит возможность создавать новые категории.
Проект должен состоять из двух функциональных частей – панели администратора и панели пользователя.

Дневники разработки → Проект Simple Tracker. Часть 8: формирование дистрибутива и итоги
Iscander Che, Simple Tracker, C++, Qt
В заключение подготовим получаемые при компиляции файлы для дистрибуции. Неважно, что проект локальный. Удобнее иметь под рукой инсталлятор, на всякий случай. С его помощью можно, например, автоматизировано очистить реестр при удалении программы с диска.
Но начнём с того, что атрибутируем исполняемый файл, как это делается в других приложениях: зададим номер версии, наименование продукта, копирайт и иконку исполняемого файла.

Дневники разработки → Проект Simple Tracker. Часть 7: сервер и клиент
Simple Tracker, Qt, Iscander Che, C++
Рассмотрим теперь сервер и клиента.
С вопросами, касающимися общей организации взаимодействия клиента и сервера, можно ознакомиться в этой статье: " Пример использования QLocalServer и QLocalSocket ". Здесь я коснусь лишь моментов, непосредственно связанных с передачей информации по задаче и закрытием задачи.
Сервер
// trackerserver.cpp TrackerServer::TrackerServer(QWidget* parent) : QWidget(parent) { // Задаём имя сервера nameServer = "TrackerServer"; // Устанавливаем размер следующего блока равным нулю nextBlockSize = 0; ... } // Метод создания и запуска сервера void TrackerServer::createServer() { localServer = new QLocalServer(this); // Если сервер не запустить, выдать сообщение и завершить программу if(!localServer->listen(nameServer)) { QMessageBox::critical(0, tr("Ошибка сервера"), tr("Невозможно запустить сервер ") + nameServer + ": " + localServer->errorString()); localServer->close(); return; } } ... // Метод создания подключений void TrackerServer::createConnections() { // Подключение сигнала сервера о новом подключении к обработчику нового подключения connect(localServer, &QLocalServer::newConnection, this, &TrackerServer::slotNewConnection); ... }

Дневники разработки → Проект Simple Tracker. Часть 6: сервер. Слоты сервера
C++, Qt, Iscander Che, Simple Tracker
Слоты, имеющие отношение непосредственно к серверу, мы рассмотрим в связке с клиентом. Пока же сосредоточимся на тех слотах, которые относятся к управлению проектами и задачами и общих слотах приложения.
Начнём с соединений. Их я вынес в отдельный метод void TrackerServer::createConnections() .
// trackerserver.cpp // Метод создания подключений void TrackerServer::createConnections() { // Установка текущего проекта connect(projectView, &QListView::clicked, this, &TrackerServer::slotSetCurrentProject); connect(projectView, &QListView::activated, this, &TrackerServer::slotSetCurrentProject); // Подключение сигнала о смене статуса к обработчику connect(statusDelegate, &ComboBoxDelegate::commitData, this, &TrackerServer::slotChangeTaskStatus); // Создание новой задачи connect(newTaskButton, &QPushButton::clicked, this, &TrackerServer::slotNewTask); // Редактирование существующей задачи connect(editTaskButton, &QPushButton::clicked, this, &TrackerServer::slotEditTask); connect(taskView, &QTableView::doubleClicked, this, &TrackerServer::slotEditTask); // Удаление существующей задачи connect(deleteTaskButton, &QPushButton::clicked, this, &TrackerServer::slotDeleteTask); // Создание нового проекта connect(newProjectButton, &QPushButton::clicked, this, &TrackerServer::slotNewProject); // Архивация существующего проекта connect(archiveProjectButton, &QPushButton::clicked, this, &TrackerServer::slotArchiveProject); // Открытие архива проектов connect(openArchiveButton, &QPushButton::clicked, this, &TrackerServer::slotOpenArchive); // Открытие окна трекера connect(actionOpenWindow, &QAction::triggered, this, &TrackerServer::slotOpenTrackerWindow); // Открытие окна трекера по двойному клику на иконке в трее connect(trayIcon, &QSystemTrayIcon::activated, this, &TrackerServer::slotDoubleClickOpenTrackerWindow); // Завершение работы трекера connect(actionQuit, &QAction::triggered, qApp, &QApplication::quit); // Открытие окна настроек приложения connect(actionSettings, &QAction::triggered, this, &TrackerServer::slotOpenSettingsWindow); }

Дневники разработки → Про итераторы
Когда в четвёртый раз в одном месте написал нечто подобное:
QStringList list; // наполняем list по условию, т.е. элементов там может и не оказаться if(!list.isEmpty()) { foreach(QString str, list) { // обходим каждый найденный элемент } }
неожиданно осознал, для чего бывают итераторы.
Не то, чтобы какое-нибудь открытие. Про итераторы я знаю. Только до сегодняшнего дня в голову не приходило их использовать. Всегда хватало foreach , или на совсем уж крайний случай for , когда надо в обработке надо опираться на идентификатор элемента списка. И получилось красивее:
QListIterator<QString> listIterator(list); while(listIterator.hasNext()) { // обрабатываем элементы списка, если они есть }
Жаль, что нельзя из итератора извлечь идентификатор элемента...

Дневники разработки → Проект Simple Tracker. Часть 5: сервер. Модель данных задач и представление
Simple Tracker, Iscander Che, C++, Qt
Рассмотрим подробно таблицу задач.
По требованиям, указанным вначале, таблица должна была выглядеть так.
На момент разработки стало понятно, что логика работы отдельно стоящего выпадающего списка становится сложной, и было принято решение реализовать его через делегата. Поэтому таблица теперь выглядит так.
Вначале реализуем делегата, потом займёмся заливкой цветом и запретом редактирования ячеек.

Дневники разработки → Проект Simple Tracker. Часть 4: сервер. Модели данных и GUI основного окна приложения
Iscander Che, Simple Tracker, Qt, C++
Теперь подробно рассмотрим внутреннее устройство самого трекера и его графического окружения.
Эта часть, с одной стороны, важная, поскольку модели данных служат для перехода от базы данных к использованию данных. С другой стороны, она немного скучная, в части формирования GUI.
Когда я начал работу над проектом, я ещё не знал, как правильно с помощью Qt Desinger установить QSplitter (вот статья, где подробно описано, как это всё-таки можно сделать: https://evileg.com/post/73/ ). Поэтому дизайн окна писал через код. Пришлось потратить вечер, чтобы немного разобраться. И на этот проект я решил писать все окна, в том числе и диалоги, через код. Вначале это было утомительно, но на диалогах стало удобнее: большинство диалогов имеют кнопки ОК и Cancel, и части кода, описывающие сами кнопки, их размещение, сигнально-слотовые соединения и сами слоты можно было спокойно копировать. Конечно, на совсем простеньких диалогах-вопросах можно использовать QMessageBox, но меня огорчил внешний вид итоговых окон. Возможно, надо повозиться с размерами, чтобы фразы отображались красиво, но я не захотел. Зато автоматическое размещение компонентов прямо из кода меня вполне устроило.

Дневники разработки → Проект Simple Tracker. Часть 3: сервер. База данных и её тестирование
Simple Tracker, Qt, Iscander Che, C++
Базу данных я буду реализовывать на SQLite. В базе должно быть размещено две таблицы: для проектов и для задач. Таблицы в базе данных независимы друг от друга. Все переменные для базы данных и таблиц сделаны глобальными для единообразия.

Qt → Пример использования QLocalServer и QLocalSocket
В статье описывается использование QLocalServer и QLocalSocket. Пример является переработкой кода из книги Шлее «Qt 5.3. Профессиональное программирование на C++», посвящённого QTcpServer и QTcpSocket соответственно. Не смотря на то, что наименования классов похожи, и используются в одном и том же модуле, пара существенных отличий есть. Их мы рассмотрим по ходу изложения.
QLocalServer и QLocalSocket реализуют механизмы именованных каналов или сокетов домена Unix. Подробнее об этом можно почитать здесь и здесь .
Пример состоит из двух частей. В первой реализуется QLocalServer, во второй – QlocalSocket.
Сервер реализует следующий функционал: на монитор выводится виджет с текстовым полем, в котором будет отображаться информация, поступающая извне, от сокета. Сервер ожидает входящих соединений и, в случае успешного подключения, отправляет сокету сообщение об этом. Кроме того, сервер ретранслирует сокету передаваемую от сокета информацию.
В свою очередь, сокет выводит на монитор виджет с текстовым полем и кнопкой. В текстовом поле отображается информация, поступающая от сервера и служебная информация самого сокета (обнаружение подключения в начале сеанса или ошибка подключения к серверу в случае его недоступности). По нажатию кнопки сокет отправляет информацию серверу.
Timeweb
Позвольте мне порекомендовать вам отличный хостинг, на котором расположен EVILEG.
В течение многих лет Timeweb доказывает свою стабильность.
Для проектов на Django рекомендую VDS хостинг
Посмотреть Хостинг