Суббота, 04.04.2020 03:04

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

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

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

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

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

Создадим новый класс 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

Мы объявили новый класс - 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"

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

 

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

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

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

В Qt для сохранения состояния объектов используется 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-файлах.

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

Заключение

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

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

Категория Qt
Теги Cpp QtCreator Qt

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

Простой текст

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Строки и абзацы переносятся автоматически.
  • Адреса веб-страниц и email-адреса преобразовываются в ссылки автоматически.
Просмотров: 59