Доброго времени суток. Недавно загорелся идеей написать простой, но функциональный плагин для среды разработки Qt Creator, предназначенный для визуализации данных об использовании оперативной памяти и загрузки ЦП текущим запущенным процессом. В качестве вдохновения для меня послужил инструментарий «Средства диагностики», присутствующий в Visual Studio. Ниже я расскажу об основных деталях разработки.
Так как тема создания плагинов для Qt Creator уже подробно описана на хабре, например, в статье Система расширений Qt Creator, то поэтому не буду останавливаться на общей информации и перейду сразу к описанию плагина.
Собственно, для того, чтобы получить информацию о любом запущенном в операционной системе процессе для начала необходимо узнать его идентификатор (PID). Вопросом получения PID запущенного через Qt Creator процесса я и занялся в первую очередь. После безрезультатного гугления на эту тему я перешел к изучению исходников Qt Creator, в ходе чего обнаружил, что узнать искомые данные довольно просто. Для этого нужны поймать следующие сигналы, испускаемые статическим экземпляром ProjectExplorer::ProjectExplorerPlugin::instance():
void runControlStarted(ProjectExplorer::RunControl *rc);
void updateRunActions();
void runControlFinished(ProjectExplorer::RunControl *rc);
// connects
connect(ProjectExplorer::ProjectExplorerPlugin::instance(),
&ProjectExplorer::ProjectExplorerPlugin::runControlStarted,
this, &DiagnosticToolsPlugin::onRunControlStarted);
connect(ProjectExplorer::ProjectExplorerPlugin::instance(),
&ProjectExplorer::ProjectExplorerPlugin::runControlFinished,
this, &DiagnosticToolsPlugin::onRunControlFinished);
connect(ProjectExplorer::ProjectExplorerPlugin::instance(),
&ProjectExplorer::ProjectExplorerPlugin::updateRunActions,
this, &DiagnosticToolsPlugin::onUpdateRunActions);
// slots
void DiagnosticToolsPlugin::onRunControlStarted(ProjectExplorer::RunControl *rc){
m_runControlPtr = rc;
}
void DiagnosticToolsPlugin::onUpdateRunActions(){
if(m_runControlPtr){
m_dataQueryEngine->setPid(m_runControlPtr->applicationProcessHandle().pid());
m_dataQueryEngine->startDataQuery();
}
}
void DiagnosticToolsPlugin::onRunControlFinished(ProjectExplorer::RunControl *rc){
Q_UNUSED(rc)
m_runControlPtr = NULL;
m_dataQueryEngine->stopDataQuery();
}
Получив сигнал void runControlStarted(ProjectExplorer::RunControl *rc), запоминаем указать m_runControlPtr на объект ProjectExplorer::RunControl *rc и далее в слоте onUpdateRunActions() узнаем PID. Отслеживание сигнала updateRunActions оказалось необходимым по причине того, что после сигнала runControlStarted значение PID в объекте ProjectExplorer::RunControl *rc было еще не известно(равно нулю).
Следующие задачи были тривиальными. В операционной системе Windows информация об используемой процессом памяти и загрузке ЦП была получена через WinApi, в Linux — посредством анализа содержимого файлов /proc/pid/stat и /proc/stat.
Финальный штрих — визуализация собранной информации. Первой мыслью было использовать модуль Qt для построения графиков Qt Charts, но в виду того, что данный компонент не является частью Qt Creator из коробки и по причине простоты решаемой мною задачи, в итоге было решено реализовать свой класс для рисования графиков. Закончив работу с GUI, я стал думать, где разместить созданную графическую форму. С одной стороны, было бы логично поместить ее снизу вместе с остальными панелями вывода, с другой — хотелось бы видеть одновременно и вывод приложения и информацию об используемых им ресурсах компьютера. Поэтому было принято волевое (возможно, неудачное) решение поместить графическую форму на левую боковую панель. И вот, что получилось в итоге:
Заключение
В статье было описано, что уже сделано на данный момент. Далее планируется создать версию под Mac OS и добавить окно настроек, в котором будет присутствовать возможность задать интервал опроса, шаг на графике, цвет и т. д. Может быть, кто-нибудь подкинет другие идеи по улучшению. Посмотреть исходный код и скачать плагин можно здесь.
Всем спасибо за внимание.
Автор: рыцарь со стволом