|
Символы кириллицы выводит некорректно. Как сделать чтобы выводился читабельный текст на русском языке? Тип приложения - не 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. В следующем параграфе мы познакомимся со средствами для прорисовки виджетов на экране.