Пишем «плавающее» окно на qt5. Часть 3. Новое подменю и сохранение позиции окна. - АлтунинВВ.Блог - всё об IT-технологиях!
Суббота, 04 апреля 2020 14:04

Пишем «плавающее» окно на qt5. Часть 3. Новое подменю и сохранение позиции окна.

Россия

Это третья часть, предыдущие части вы можете найти на моем сайте: часть 1, часть 2.

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

Если у вас нет готового проекта с предыдущего урока, вы можете скачать его с github.com.

Добавляем заголовок в подменю

Создадим новый C++ класс

Щелкнем по Sources и выберем Add new…

Выберем С++ и C++ Class

В следующем окне в Class name введем TextSeparator

Жмем Next и создаем класс, открываем файл textseparator.cpp и заменяем его содержимое следующим кодом:

#include "textseparator.h"
#include <QLabel>
#include <QWidgetAction>
TextSeparator::TextSeparator(QObject *parent, QString text, QString bgColor, QString textColor) : QWidgetAction(parent)
{
    QLabel* tLabel = new QLabel(text);
    tLabel->setMinimumHeight(26);
    tLabel->setStyleSheet("background: "+bgColor+"; color: "+textColor+"; font-weight: bold;");
    tLabel->setAlignment(Qt::AlignCenter);
    this->setDefaultWidget(tLabel);
}

Нажимаем F4 и заменяем содержимое файла кодом:

#ifndef TEXTSEPARATOR_H
#define TEXTSEPARATOR_H
#include <QObject>
#include <QWidget>
#include <QWidgetAction>
class TextSeparator : public QWidgetAction
{
    Q_OBJECT
public:
    TextSeparator(QObject *parent, QString text, QString bgColor, QString textColor);
};
#endif // TEXTSEPARATOR_H

1. Мы объявили новый класс - TextSeparator являющийся потомком QWidgetAction Это сделано для того, чтобы можно было сразу передать объект класса в QMenu при создании разделителя.

2. Мы объявили конструктор класса, чтобы сразу задать текст для нашего сепаратора, цвет фона и текста.

3. В реализации конструктора мы создаем QLabel, задаем высоту для неё, стиль и выравнивание.

4. Мы задаем QLabel виджетом по-умолчанию, таким образом QWidgetAction будет использовать его при отрисовке пункта меню.

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

Теперь на нужно добавить наш заголовок в подменю.

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

subMenuHeader = new TextSeparator(NULL,"Clocks","#999","#fff");
conextMenu
->addAction(subMenuHeader);
conextMenu->addAction(quitAct);

Удалим из void FloatWindow::contextMenuEvent(QContextMenuEvent *event) строку 

conextMenu->addAction(quitAct);

Нажмем F4 и добавим в конец private:

TextSeparator* subMenuHeader;

не забудьте добавить

#include "textseparator.h"

Запускаем сборку и любуемся новым подменю

 

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

Сохранение положения «плавающего окна»

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

В Qt5 для сохранения состояния объектов используется QSettings

Этот класс позволяет легко и просто сохранять любые значения QString, QRect, и QImage.

Откроем floatwindow.h и добавим после

TextSeparator* subMenuHeader;

строки

void saveWidgetPosition();
void readWidgetPosition(); 

После void mouseMoveEvent(QMouseEvent *evt);

добавим

void mouseReleaseEvent(QMouseEvent *evt);

Нажмем F4 и добавим в конец файла

void FloatWindow::saveWidgetPosition()
{
    QSettings settings("AltuninVV", "Clocks");
    settings.beginGroup("FloatWindow");
        settings.setValue("pos", pos());
    settings.endGroup();
}
void FloatWindow::readWidgetPosition()
{
    QSettings settings("AltuninVV", "Clocks");
    settings.beginGroup("FloatWindow");
        QPoint oldPoint = settings.value("pos", QPoint(0, 0)).toPoint();
        if (oldPoint.x()!=0 && oldPoint.y()!=0) //if no prev values just do nothing
        {
            move(settings.value("pos", QPoint(0, 0)).toPoint());
        }
    settings.endGroup();
}
void FloatWindow::mouseReleaseEvent(QMouseEvent *evt)
{
    saveWidgetPosition();
}

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

readWidgetPosition();

Не забудьте добавить требующиеся #include

Запустим сборку проекта Ctrl+R и переместим окно в новую позицию. Теперь при повторном запуске окно появится на старом месте.

Давайте разберемся, как это работает:

Класс QSettings не зависит от операционной системы. В зависимости от OS он автоматически выбирает место для сохранения данных:

1. В Windows данные хранятся в реестре, если вы откроете редактор реестра regedit.exe то вы сможете найти сохраненные настройки в ветке: Компьютер\HKEY_CURRENT_USER\Software\AltuninVV\Clocks\FloatWindow

2. Unix-подобные системы — настройки хранятся в ini-файлах

 3. MacOS и iOS – настройки хранятся в .plist-файлах.

Заключение

На этом всё, мы смогли немного украсить наше всплывающее меню и добавили функционал, сохраняющий позицию нашего «плавающего» окошка после выхода из программы. 

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

Прочитано 311 раз Последнее изменение Суббота, 04 апреля 2020 14:39