Float window over source code

Сегодня с помощью QtCreator и C++ мы реализуем простое «плавающее» окно – часы. Работать мы будем в Windows 10. Материал будет разбит на несколько частей.

Создавая программы, программист зачастую сталкивается с необходимостью вывода разнообразной информации на экран. Для этого обычно используются разнообразные всплывающие окна или окна диалог

Если же необходимо показывать пользователю достаточно часто изменяющуюся информацию, например, скорость загрузки/скачивания информации, вывод какого-либо графика – то тут лучше использовать «плавающее» окно.

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

Яндекс.Браузер умеет откреплять любое видео в виде плавающего окна, что очень удобно.

Так же, «плавающее» окно использует программа Download Master. 

Создание проекта

Откроем Qtcreator и создадим проект Qt Widgets Application для декстопа.

Назовем его QtFloatWindow.

В качестве «Build System» выберем qmake.

Класс окна оставим без изменений.

Пробный запуск

Сразу после создания, проект откроется в редакторе, нам нужно проверить собирается ли у нас проект в принципе.

Раскрываем папку с проектом и открываем файл mainwindow.cpp

Нажимаем Ctrl+R, будет запущена сборка проекта.

Возможно в процессе сборки вы получите сообщение об ошибке:

Жмем Yes.

Это ошибка:

C:\msys64\mingw64\share\qt5\mkspecs\common\windows-vulkan.conf:1: error: Cannot find feature windows_vulkan_sdk

Её можно спокойно игнорировать, если, конечно, вы не используете Vulkan API для разработки под windows.

Если более серьезных ошибок не возникло и среда сборки у вас настроена верно, то появится такое вот окно:

Вот и всё, текст прошел успешно можно закрывать окно.

Добавление формы для плавающего окошка

Пришло время заняться непосредственно плавающим окном.

Добавим новую форму в проект. Для этого щелкаем правой кнопкой на название проекта и выбираем Add new…

В новом выбираем Qt и Qt Designer Form Class и жмем Choose…

На следующей форме выбираем Widget и жмем Next

Задаем имя новой формы в поле Class name: FloatWindow

Жмем Next и сразу Finish

Откроется наша, только что созданная, форма:

В свойствах формы в блоке geometry задаем новые размеры формы, пусть это будет:

Width: 200

Height: 70

Размеры окна, в редакторе, изменяться в соответствии с заданными размерами.

Тестирование новой формы

Если мы сейчас запустим сборку проекта, то после его запуска не увидим новую форму. Нам нужно вручную добавить код для его создания.

Откроем mainwindow.cpp

Добавим в начало файла:

[code]#include "floatwindow.h"[/code]

В конец MainWindow::MainWindow(QWidget *parent) добавим:

[code]
FloatWindow *fwin = new FloatWindow();    
fwin->show();
[/code]

У нас получится:

[code]
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "floatwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)

{
    ui->setupUi(this);

    FloatWindow *fwin = new FloatWindow();
    fwin->show();
}

MainWindow::~MainWindow()
{
    delete ui;
}
[/code]

Запускаем проект Ctrl+R

Откроется наше большое окно, если вы его свернем, то под ним окажется наша новая форма:

Добавление компонентов на форму

Займемся внешним видом нашей формы, откроем её в редакторе и перетащим новый компонент Widget из области со списком компонентов.

Так же перетащим на Label на только что созданный Widget. Вы можете его перетащить и сбросить не только непосредственно на форму, но и на имя widget в списке компонентов формы.

В списке справа выбираем нашу форму – FloatWindow

Правой кнопкой вызываем меню и выбираем Lay Out -> Lay Out Horizontally.

В списке справа выбираем нашу форму – Widget

Правой кнопкой вызываем меню и выбираем Lay Out -> Lay Out Horizontally.

Выбираем widget и в поле objectName вводим новое значение для нее – centralwidget

Выбираем label и в поле objectName вводим новое значение для нее – clockLabel

Выбираем label

Обратите внимание, так как мы использовали Layout, то изменять размер Label мы не можем.

В окне свойств пролистайте вниз до свойств QLabel

В поле Text вводим 00:00:00

В поле alignment для Horizontal выставляем AlignHCenter

Листаем вверх и выставляем размер шрифта равным 30

У нас получится следующее:

Теперь уберем ненужные отступы.

В списке справа выделяем FloatWindow и пролистываем свойства до самого низа – Layout

Меняем все значения равные 9 или 6 на 0. Таким образом мы убираем ненужные отступы.

Повторяем тоже самое для centralwidget

Делаем из формы «плавающее» окно

Открываем floatwindow.cpp и добавляем код в  FloatWindow::FloatWindow(QWidget *parent)

[code]
setStyleSheet("#centralwidget { background-color: rgba(255, 255, 255, 100); border:1px solid #eee; }");

setAttribute(Qt::WA_TranslucentBackground);

setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);    
[/code]

Запускаем, чтобы проверить что получилось – Ctrl-R.

Вот у нас и получилось нечто похожее на «плавающее» окошко, правда сдвинуть его не получиться, так как заголовки и границы у формы мы скрыли.

Учим окно перемещаться по экрану

Давайте добавим код, позволяющий нам его перемещать по экрану.

Открываем floatwindow.cpp и добавляем в конец файла:

[code]
void FloatWindow::mousePressEvent(QMouseEvent *evt)
{
    oldPos = evt->globalPos();
}

void FloatWindow::mouseMoveEvent(QMouseEvent *evt)
{
    const QPoint delta = evt->globalPos() - oldPos;
    move(x()+delta.x(), y()+delta.y());
    oldPos = evt->globalPos();
}
[/code]

Нажимаем F4 и добавляем

QPoint oldPos;

после

Ui::FloatWindow *ui;

Добавляем

[code]
protected:
     void mousePressEvent(QMouseEvent *evt);
     void mouseMoveEvent(QMouseEvent *evt);
[/code]

после 

[code]
private:
   Ui::FloatWindow *ui;
   QPoint oldPos;
[/code]

Добавляем

#include <QMouseEvent>

В начало файла.

Запускаем сборку Ctrl-R.

Вот и наше полупрозрачное окошко:

Просто щелкаем на нем левой кнопкой мыши и не отпуская перетаскиваем в нужное место на экране.

Заключение

Подведем итоги, мы узнали:

  1. Как добавить еще одну форму к проекту;
  2. Как правильно добавить компоненты на форму и настроить отступы;
  3. Как превратить обычную форму в «плавающее» окно;
  4. Добавили функционал перемещения окна в любое место экрана.

Вот и всё на сегодня. В следующем материале мы добавим контекстное меню для плавающего окна и заставим часы идти.

Готовый проект вы можете найти на github по ссылке.