Символы кириллицы выводит некорректно. Как сделать чтобы выводился читабельный текст на русском языке? Тип приложения - не Qt, Qt Creator 4.5.0 основан на Qt 5.10.0. Win7.
|
Собственные классы в Qt. Создание элементов графического интерфейса
14.5 Создание собственного элемента интерфейса. Создание свойств
QObject предоставляет механизм для объявления свойств. Свойства — это специальные общедоступные поля, через которые можно получить доступ к данным объекта. Свойства обычно имеют методы для установки и получения значения, вызываемые при чтении из свойства и записи данных. В Qt свойства выполняют специальную роль, ведь делают доступными для метаобъектной системы способы чтения и записи данных объектов, что часто используется в Qt для реализации различных механизмов (анимации, описание динамических пользовательских интерфейсов в QtQuick, и т. д.).
Определение свойства обычно состоит из макроса Q_PROPERTY, который описывает свойство и содержит описания:
- метода для установки начального значения;
- метода для получения значения;
- метода для установки значения;
- сигнала об изменении значения свойства;
- дополнительных настроек.
Метод для установки значения принимает одно значение (того же типа, что и свойство) и возвращает void. Метод для получения значения возвращает значение свойства.
Обычно метод для получения значения называют так же как и свойство, а метод для установки значения ещё и имеет префикс "set". Метод для получения значения, который возвращает тип bool также обычно имеет префикс "is", например:
QStirng Text( ) const; void setText ( const QString &Text); bool isVisible ( ) const; void setVisible ( bool isVisible );
Наличие отдельного метода для установки значения позволяет запрограммировать дополнительные действия, а также проверить допустимость значения, которое устанавливается. В свою очередь, отдельные методы для установки значения дают возможность косвенного использования уже существующих свойств. Изменение значения свойства возможно, как через прямое использование методов установки и получения значения свойства, так и используя средства метаобъектной системы Qt. Также есть возможность определения доступных свойств во время выполнения программы.
Мы рассмотрим определение свойств на примере создания собственного виджета-индикатора LedIndicator, который будет находиться в одном, включённом или выключенном, состоянии в зависимости от значения свойства.
Для начала, создадим оконный проект и добавим к нему класс LedIndicator, унаследованный от QWidget:
class LedIndicator : public QWidget { Q_OBJECT Q_PROPERTY( QString TextREAD TextWRITE setText ) Q_PROPERTY( bool turnedOn READ isTurnedOn WRITE setTurnedOn NOTIFY state toggled ) public : explicit LedIndicator ( QWidget * parent = 0 ); QString Text( ) const; bool isTurnedOn ( ) const; signals : void state toggled ( bool ); public slots : void setText ( const QString &); void setTurnedOn ( bool ); private : QString mText; bool mIsTurnedOn; };
Мы определили два свойства: text типа QString для надписи, а также turnedOn типа bool для состояния индикатора. Специальные слова READ и WRITE в описании свойства обозначают названия методов для установления и изменения значения свойства. В описании второго свойства использовано слово NOTIFY для обозначения названия сигнала, который будет сообщать об изменении свойства. Добавим реализацию для класса:
#include <QPainter> #include <QPaintEvent> //Радиус индикатора const int cLedRadius = 7; //Отступ между индикатором и надписью const int cLedSpacing = 5; LedIndicator::LedIndicator ( QWidget * parent ) : QWidget ( parent ), mIsTurnedOn ( false ) //Инициализируем начальным значением! { } //Метод получения значения — свойство text QString LedIndicator::Text( ) const { return mText; } //Метод получения значения — свойство turnedOn bool LedIndicator::isTurnedOn ( ) const { return mIsTurnedOn; } //Метод установки значения — свойство text void LedIndicator::setText ( const QString &pText ) { mText = pText; } //Метод установки значения — свойство turnedOn void LedIndicator::setTurnedOn ( bool pIsTurnedOn ) { //Проверка уже установленного значения if ( isTurnedOn ( ) == pIsTurnedOn ) { return; } mIsTurnedOn = pIsTurnedOn; //Выпускаем сигнал про изменение em it state toggled ( mIsTurnedOn ); //Вызываем метод QWidget::update(), который добавляет в очередь событий QPaintEvent //для того чтобы перерисовать наш виджет в соответствии с установленным isTurnedOn() update ( ); }
Обратите внимание: в большинстве случаев при создании собственных слотов, которые получают и устанавливают значения, следует сравнивать переданное значение с текущим и запрещать выполнение тела слота, если переданное и текущее значения равны. Особенно за этим необходимо следить, если слот выдаёт сигнал об изменении значения. Об этом необходимо помнить, чтобы избежать бесконечной рекурсии и аварийного завершения программы в случае перекрёстного сигнально-слотового соединения между такими слотами. Именно такую проверку мы выполнили в методе setTurnedOn() перед отправкой сигнала об изменении и перерисовкой.
Теперь осталось создать для нашего индикатора соответствующий вид. Как мы отметили, существует два способа создать собственный виджет: составить из готовых виджетов, упорядочив их размещение и геометрию, или нарисовать виджет средствами Qt. В следующем параграфе мы познакомимся со средствами для прорисовки виджетов на экране.