Пример "Styles"Файлы:
Изображения: Пример "Styles" иллюстрирует, как создать пользовательские стили прорисовки виджета, используя Qt, а также демонстрирует предварительно определённые стили Qt. Стиль в Qt является подклассом QStyle или одного из его подклассов. Стили выполняют прорисовку от имени виджетов. Qt предоставляет весь спектр предопределенных стилей, как встроенных в библиотеку QtGui, так и находящихся в подключаемых модулях. Пользовательские стили обычно создаются путем наследования одного из существующих стилей Qt и переопределением некоторых виртуальных функций. В данном примере пользовательский стиль называется NorwegianWoodStyle и наследуется от QMotifStyle. Его основными особенностями являются текстуры дерева, используемые для заполнения большинства виджетов, а также закругленные кнопки и выпадающие списки. Для реализации стиля мы используем несколько передовых особенностей, предоставляемых QPainter, таких как сглаживание (для получения сглаженных углов кнопок), использование альфа-каналов (для создания у кнопок эффекта вдавленности или выпуклости) и рисование траекторий (для заливки кнопок и рисования контуров). Мы также будем использовать множество возможностей классов QBrush и QPalette. Пример состоит из следующих классов:
Определение класса NorwegianWoodStyleВот определение класса NorwegianWoodStyle: class NorwegianWoodStyle : public QMotifStyle { Q_OBJECT public: NorwegianWoodStyle() {} void polish(QPalette &palette); void polish(QWidget *widget); void unpolish(QWidget *widget); int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const; int styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const; void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const; void drawControl(ControlElement control, const QStyleOption *option, QPainter *painter, const QWidget *widget) const; private: static void setTexture(QPalette &palette, QPalette::ColorRole role, const QPixmap &pixmap); static QPainterPath roundRectPath(const QRect &rect); }; Все открытые функции, объявленные в QStyle (родителе класса QMotifStyle), переопределены здесь для подмены внешнего вида и поведения Motif. Закрытые функции являются вспомогательными. Реализация класса NorwegianWoodStyleТеперь рассмотрим реализацию класса NorwegianWoodStyle. void NorwegianWoodStyle::polish(QPalette &palette) { QColor brown(212, 140, 95); QColor beige(236, 182, 120); QColor slightlyOpaqueBlack(0, 0, 0, 63); QPixmap backgroundImage(":/images/woodbackground.png"); QPixmap buttonImage(":/images/woodbutton.png"); QPixmap midImage = buttonImage; QPainter painter; painter.begin(&midImage); painter.setPen(Qt::NoPen); painter.fillRect(midImage.rect(), slightlyOpaqueBlack); painter.end(); Функция polish() переопределена от QStyle. Она получает QPalette как ссылку и адаптирует палитру для соответствия стилю. Большинство стилей не нуждается в переопределении этой функции. Стиль Norwegian Wood переопределяет эту функцию для создания «деревянной» палитры. Мы начинаем с определения некоторых необходимых экземпляров QColor. Потом читаем два изображения в формате PNG. Префиксы : в пути файла указывают на то, что файлы PNG являются встроенными ресурсами.
Переменная midImage инициализирована значением buttonImage, но потом мы используем QPainter и заполняем её черным цветом с 25% прозрачности (черный цвет со значением альфа-канала 63). В результате получается несколько более темное изображение, чем buttonImage. Это изображение будет использоваться для заполнения кнопок, которые пользователь удерживает в нажатом состоянии. palette = QPalette(brown); palette.setBrush(QPalette::BrightText, Qt::white); palette.setBrush(QPalette::Base, beige); palette.setBrush(QPalette::Highlight, Qt::darkGreen); setTexture(palette, QPalette::Button, buttonImage); setTexture(palette, QPalette::Mid, midImage); setTexture(palette, QPalette::Window, backgroundImage); QBrush brush = palette.background(); brush.setColor(brush.color().dark()); palette.setBrush(QPalette::Disabled, QPalette::WindowText, brush); palette.setBrush(QPalette::Disabled, QPalette::Text, brush); palette.setBrush(QPalette::Disabled, QPalette::ButtonText, brush); palette.setBrush(QPalette::Disabled, QPalette::Base, brush); palette.setBrush(QPalette::Disabled, QPalette::Button, brush); palette.setBrush(QPalette::Disabled, QPalette::Mid, brush); } Мы инициализируем палитру. Палитры выполняют различные цветовые роли, такие как QPallete::Base (используется для заливки текстовых редакторов, элементов представлений и так далее), QPallete::Text (используется для текста на переднем плане) и QPalette::Background (используется для фона большинства виджетов). Каждая роль имеет имеет собственный QBrush, который обычно является сплошным цветом, но также может быть шаблоном кисти или даже текстурой (QPixmap). В дополнение к ролям палитры имеют различные цветовые группы: активную, выключенную и неактивную. Активная цветовая группа используется для рисования виджетов в активном окне. Отключённая группа используется для отключённых виджетов. Неактивная группа используется для всех остальных виджетов. Большинство палитр имеют идентичные активную и неактивную группы, в то время как отключённая группа использует более темные цвета. Мы инициализируем объект QPalette коричневым цветом. Qt автоматически производит все цвета ролей для всех цветовых групп, исходя из одного этого цвета. Потом мы перезаписываем некоторые значения, установленные по умолчанию. Например, мы используем Qt::darkGreen вместо установленного по умолчанию (Qt::darkBlue) для роли QPalette::Highlight. QPalette::setBrush() перезаписывается, чтобы мы использовали одинаковый цвет или кисть для всех трех цветовых групп. Функция setTexture() является закрытой функцией, устанавливающей текстуры для определенных цветовых ролей, сохраняя при этом существующий цвет в QBrush. QBrush может содержать как сплошные цвета, так и текстуры одновременно. Сплошные цвета используются для рисования текста и других графических элементов, в которых текстуры были бы излишни или смотрелись бы плохо. Наконец, мы устанавливаем кисть для отключённой цветовой группы. Мы используем woodbackground.png в качестве текстуры для всех отключённых виджетов, включая кнопки, и темный цвет для сопровождения текстуры. Давайте перейдем к другим функциям, переопределяемым от QMotifStyle: void NorwegianWoodStyle::polish(QWidget *widget) { if (qobject_cast<QPushButton *>(widget) || qobject_cast<QComboBox *>(widget)) widget->setAttribute(Qt::WA_Hover, true); } Данная перегруженная функция QStyle::polish() вызывается для каждого виджета, рисуемого в этом стиле. Мы переопределили ее, чтобы установить свойство Qt::WA_Hover на QPushButton и QComboBox. Если данные свойства установлены, то Qt генерирует события рисования, когда указатель мыши входит в зону виджета или покидает ее. Это позволяет прорисовывать кнопки и выпадающие списки по-разному, когда указатель находится над ними. void NorwegianWoodStyle::unpolish(QWidget *widget) { if (qobject_cast<QPushButton *>(widget) || qobject_cast<QComboBox *>(widget)) widget->setAttribute(Qt::WA_Hover, false); } Данная перегруженная функция QStyle::unpolish() вызывается для отмены любых модификаций, сделанных для виджета в polish(). Для простоты мы будем считать, что флаг не был установлен до вызова функции polish(). В идеале мы должны бы помнить оригинальное состояние каждого виджета (например, при помощи QMap<QWidget *, bool>) и восстанавливать его в unpolish(). int NorwegianWoodStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const { switch (metric) { case PM_ComboBoxFrameWidth: return 8; case PM_ScrollBarExtent: return QMotifStyle::pixelMetric(metric, option, widget) + 4; default: return QMotifStyle::pixelMetric(metric, option, widget); } } Функция pixelMetric() возвращает размер в пикселях для определенных элементов пользовательского интерфейса. При переопределении этой функции мы можем влиять на способ прорисовки определенных виджетов и их подсказке о размере. Здесь мы возвращаем 8 в качестве ширины поля вокругQComboBox, таким образом обеспечивая достаточное количество места вокруг текста и стрелки для скругленных углов Norwegian Wood. Значение по умолчанию для стиля Motif равно 2. Мы также меняем величины QScrollBars, т.е. высоту горизонтальной полосы прокрутки и ширину вертикальной полосы прокрутки, чтобы сделать их на 4 пиксела больше, чем в стиле Motif. Это придаст стилю большую отличительность. Для всех других элементов QStyle::PixelMetric мы используем установки Motif. int NorwegianWoodStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const { switch (hint) { case SH_DitherDisabledText: return int(false); case SH_EtchDisabledText: return int(true); default: return QMotifStyle::styleHint(hint, option, widget, returnData); } } Функция styleHint() возвращает подсказки по виджету или базовому стилю (в нашем случае это QMotifStyle) о том, как рисовать виджеты. Стиль Motif возвращает true для подсказки QStyle::SH_DitherDisabledText, что приводит к особо неприятным визуальным эффектам. Мы переписываем это поведение и возвращаем вместо этого false. Мы также возвращаем true для подсказки QStyle::SH_EtchDisabledText, что означает, что отключенный текст будет прорисован с рельефным видом (как это делает QWindowsStyle) void NorwegianWoodStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { switch (element) { case PE_PanelButtonCommand: { int delta = (option->state & State_MouseOver) ? 64 : 0; QColor slightlyOpaqueBlack(0, 0, 0, 63); QColor semiTransparentWhite(255, 255, 255, 127 + delta); QColor semiTransparentBlack(0, 0, 0, 127 - delta); int x, y, width, height; option->rect.getRect(&x, &y, &width, &height); Функция drawPrimitive() вызывается виджетами Qt для рисования разных основных графических элементов. Здесь мы переопределяем ее для прорисовки QPushButton и QComboBox с закругленными углами. Кнопочная часть этих виджетов нарисована с использованием простейшего элемента QStyle::PE_PanelButtonCommand. Параметр option, типа QStyleOption, содержит все необходимое, что мы должны знать о виджете для рисования на нем. В частности, option->rect дает прямоугольник, в котором рисуется простейший элемент. Параметр painter является объектом QPainter, который мы можем использовать для рисования на виджете. Параметр widget является собственно самим виджетом. Обычно вся информация, которая нам нужна, доступна в option и painter, поэтому в widget нет необходимости. Мы можем использовать его для исполнения специальных эффектов, например, QMacStyle использует его для анимации кнопок по умолчанию. Если вы будете его использовать, имейте в виду, что вызывающая сторона имеет право передать нулевой указатель. Мы начинаем с определения трех QColor, которые понадобятся позже. Кроме того, мы поместим компоненты x, y, width и height прямоугольника виджета в локальные переменные. Значение, использованное для альфа-каналов цветов semiTransparentWhite и semiTransparentBlack, зависит от того, находится ли указатель мыши над виджетом или нет. С момента, как мы установили атрибуты Qt::WA_Hover на QPushButton и QComboBox, мы можем полагаться на то, что флаг QStyle::State_MouseOver будет установлен, если указатель мыши находится над кнопкой. QPainterPath roundRect = roundRectPath(option->rect); int radius = qMin(width, height) / 2; Переменная roundRect является QPainterPath. QPainterPath, в свою очередь, является векторной спецификацией фигуры. Любая фигура (прямоугольник, эллипс, сплайн и прочее) или комбинация фигур может быть выражена как контур. Мы будем использовать roundRect как для заливки фона кнопки текстурой дерева, так и для рисования контуров. Функция roundRectPath() является закрытой функцией; мы вернемся к ней позже. QBrush brush; bool darker; const QStyleOptionButton *buttonOption = qstyleoption_cast<const QStyleOptionButton *>(option); if (buttonOption && (buttonOption->features & QStyleOptionButton::Flat)) { brush = option->palette.background(); darker = (option->state & (State_Sunken | State_On)); } else { if (option->state & (State_Sunken | State_On)) { brush = option->palette.mid(); darker = !(option->state & State_Sunken); } else { brush = option->palette.button(); darker = false; } } Мы определяем две переменные, brush и darker, и инициализируем их на основе состояния кнопки:
Следующий снимок экрана иллюстрирует, как QPushButton прорисовывает свои основные состояния. Для определения того, является ли кнопка плоской или нет, нам необходимо сбросить параметр option в QStyleOptionButton и проверить, содержит ли член features флаг QStyleOptionButton::Flat. Функция qstyleoption_cast() выполняет динамический сброс; если option не является QStyleOptionButton, то qstyleoption_cast() возвращает указатель на ноль. painter->save(); painter->setRenderHint(QPainter::Antialiasing, true); painter->fillPath(roundRect, brush); if (darker) painter->fillPath(roundRect, slightlyOpaqueBlack); Мы включаем сглаживание в QPainter. Сглаживание – это техника, снижающая визуальные помехи, которые происходят в процессе конвертации форм в пиксели. Для стиля Norwegian Wood мы используем его для получения сглаженных углов у закругленных кнопок. Во первых, вызываем QPainter::fillPath() для рисования заднего плана кнопки с текстурой дерева. Во вторых, вызываем fillPath() для рисования этой же области, но уже полупрозрачным черным цветом (чёрный цвет с альфа-каналом 63) для затемнения, если darker установлен в true. int penWidth; if (radius < 10) penWidth = 3; else if (radius < 20) penWidth = 5; else penWidth = 7; QPen topPen(semiTransparentWhite, penWidth); QPen bottomPen(semiTransparentBlack, penWidth); if (option->state & (State_Sunken | State_On)) qSwap(topPen, bottomPen); Далее мы рисуем контур. Левая верхняя часть контура и нижняя правая часть нарисованы с использованием различных QPen для создания 3D эффекта. Обычно верхняя левая половина контура рисуется светлее, чем нижняя правая, но если кнопка нажата или установлена, то мы меняем местами два QPen для получения вдавленного вида кнопки. int x1 = x; int x2 = x + radius; int x3 = x + width - radius; int x4 = x + width; if (option->direction == Qt::RightToLeft) { qSwap(x1, x4); qSwap(x2, x3); } QPolygon topHalf; topHalf << QPoint(x1, y) << QPoint(x4, y) << QPoint(x3, y + radius) << QPoint(x2, y + height - radius) << QPoint(x1, y + height); painter->setClipPath(roundRect); painter->setClipRegion(topHalf, Qt::IntersectClip); painter->setPen(topPen); painter->drawPath(roundRect); Мы рисуем верхнюю левую часть контура вызовом QPainter::drawPath() с соответствующей областью отсечения. Если направление компоновки справа налево вместо обычного слева направо, то мы меняем переменные х1, х2, х3 и х4 для получения корректных результатов. На рабочих столах с направлением справа налево освещение падает из верхнего правого угла вместо верхнего левого; выпуклые и вдавленные виджеты должны отрисовываться соответственно. Изображение ниже показывает, как 3D эффекты рисуются в зависимости от направления компоновки. Красная область на изображении соответствует полигону topHalf: Самый простой путь протестировать, как будет выглядеть стиль в таком освещении, запустить программу из командной строки, добавив параметр –reverse. Этот параметр будет распознан в конструкторе QApplication. QPolygon bottomHalf = topHalf; bottomHalf[0] = QPoint(x4, y + height); painter->setClipPath(roundRect); painter->setClipRegion(bottomHalf, Qt::IntersectClip); painter->setPen(bottomPen); painter->drawPath(roundRect); painter->setPen(option->palette.foreground().color()); painter->setClipping(false); painter->drawPath(roundRect); painter->restore(); } break; default: QMotifStyle::drawPrimitive(element, option, painter, widget); } } Нижняя правая часть контура нарисована в аналогичной манере. Далее мы рисуем контур в один пиксел шириной вокруг всей кнопки, используя компонент Forderground QPalette. Это завершает вариант QStyle::PE_PanelButtonCommand выражения switch. Другие простейшие элементы обрабатываются базовым стилем. Давайте теперь вернемся к другим функциям-членам NorwegianWoodStyle: void NorwegianWoodStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { switch (element) { case CE_PushButtonLabel: { QStyleOptionButton myButtonOption; const QStyleOptionButton *buttonOption = qstyleoption_cast<const QStyleOptionButton *>(option); if (buttonOption) { myButtonOption = *buttonOption; if (myButtonOption.palette.currentColorGroup() != QPalette::Disabled) { if (myButtonOption.state & (State_Sunken | State_On)) { myButtonOption.palette.setBrush(QPalette::ButtonText, myButtonOption.palette.brightText()); } } } QMotifStyle::drawControl(element, &myButtonOption, painter, widget); } break; default: QMotifStyle::drawControl(element, option, painter, widget); } } Мы переопределили QStyle::drawControl() для прорисовки текста на QPushButton в ярком цвете, когда кнопка нажата или установлена. Если параметр option указывает на объект QStyleOptionButton (по крайней мере, так должно быть), то мы скопируем объект и модифицируем его палитру, чтобы сделать QPalette::ButtonText таким же, как компонент QPalette::BrightText (при условии, что виджет не отключен). void NorwegianWoodStyle::setTexture(QPalette &palette, QPalette::ColorRole role, const QPixmap &pixmap) { for (int i = 0; i < QPalette::NColorGroups; ++i) { QColor color = palette.brush(QPalette::ColorGroup(i), role).color(); palette.setBrush(QPalette::ColorGroup(i), role, QBrush(color, pixmap)); } } Функция setTexture() является закрытой функцией, устанавливающей текстурный компонент QBrush для определенной цветовой роли для всех трёх цветовых групп (активной, отключенной и неактивной). Мы будем использовать ее для инициализации палитры Norwegian Wood в polish(QPalette &). QPainterPath NorwegianWoodStyle::roundRectPath(const QRect &rect) { int radius = qMin(rect.width(), rect.height()) / 2; int diam = 2 * radius; int x1, y1, x2, y2; rect.getCoords(&x1, &y1, &x2, &y2); QPainterPath path; path.moveTo(x2, y1 + radius); path.arcTo(QRect(x2 - diam, y1, diam, diam), 0.0, +90.0); path.lineTo(x1 + radius, y1); path.arcTo(QRect(x1, y1, diam, diam), 90.0, +90.0); path.lineTo(x1, y2 - radius); path.arcTo(QRect(x1, y2 - diam, diam, diam), 180.0, +90.0); path.lineTo(x1 + radius, y2); path.arcTo(QRect(x2 - diam, y2 - diam, diam, diam), 270.0, +90.0); path.closeSubpath(); return path; } Функция roundRectPath() является закрытой функцией, создающей объект QPainterPath для скругленных кнопок. Контур содержит восемь сегментов: четыре сегмента дуг для углов и четыре линии для сторон. Приблизительно 250 строк кода, и мы получили полнофункциональный пользовательский стиль, основанный на предопределенных стилях. Пользовательские стили могут быть использованы для создания более ясного вида приложения или семейства приложений. Класс WidgetGalleryДля полноты мы быстро рассмотрим класс WidgetGallery, который содержит большинство основных виджетов Qt и позволяет пользователю динамически менять стили. Вот определение класса: class WidgetGallery : public QDialog { Q_OBJECT public: WidgetGallery(QWidget *parent = 0); private slots: void changeStyle(const QString &styleName); void changePalette(); void advanceProgressBar(); private: void createTopLeftGroupBox(); void createTopRightGroupBox(); void createBottomLeftTabWidget(); void createBottomRightGroupBox(); void createProgressBar(); QPalette originalPalette; QLabel *styleLabel; QComboBox *styleComboBox; QCheckBox *useStylePaletteCheckBox; QCheckBox *disableWidgetsCheckBox; ... }; Вот конструктор WidgetGallery: WidgetGallery::WidgetGallery(QWidget *parent) : QDialog(parent) { originalPalette = QApplication::palette(); styleComboBox = new QComboBox; styleComboBox->addItem("NorwegianWood"); styleComboBox->addItems(QStyleFactory::keys()); styleLabel = new QLabel(tr("&Style:")); styleLabel->setBuddy(styleComboBox); useStylePaletteCheckBox = new QCheckBox(tr("&Use style's standard palette")); useStylePaletteCheckBox->setChecked(true); disableWidgetsCheckBox = new QCheckBox(tr("&Disable widgets")); createTopLeftGroupBox(); createTopRightGroupBox(); createBottomLeftTabWidget(); createBottomRightGroupBox(); createProgressBar(); Мы начнем с создания дочернего виджета. Выпадающий список Style инициализирован всеми стилями, известными QStyleFactory в дополнение к NorwegianWood. Функции create...() являются закрытыми функциями, которые настраивают различные элементы WidgetGallery. connect(styleComboBox, SIGNAL(activated(QString)), this, SLOT(changeStyle(QString))); connect(useStylePaletteCheckBox, SIGNAL(toggled(bool)), this, SLOT(changePalette())); connect(disableWidgetsCheckBox, SIGNAL(toggled(bool)), topLeftGroupBox, SLOT(setDisabled(bool))); connect(disableWidgetsCheckBox, SIGNAL(toggled(bool)), topRightGroupBox, SLOT(setDisabled(bool))); connect(disableWidgetsCheckBox, SIGNAL(toggled(bool)), bottomLeftTabWidget, SLOT(setDisabled(bool))); connect(disableWidgetsCheckBox, SIGNAL(toggled(bool)), bottomRightGroupBox, SLOT(setDisabled(bool))); Мы соединяем выпадающий список Style с закрытым слотом changeStyle(), флажок Use style's standard palette - со слотом changePalette(), а флажок Disable widgets - со слотом дочернего виджета setDisabled(). QHBoxLayout *topLayout = new QHBoxLayout; topLayout->addWidget(styleLabel); topLayout->addWidget(styleComboBox); topLayout->addStretch(1); topLayout->addWidget(useStylePaletteCheckBox); topLayout->addWidget(disableWidgetsCheckBox); QGridLayout *mainLayout = new QGridLayout; mainLayout->addLayout(topLayout, 0, 0, 1, 2); mainLayout->addWidget(topLeftGroupBox, 1, 0); mainLayout->addWidget(topRightGroupBox, 1, 1); mainLayout->addWidget(bottomLeftTabWidget, 2, 0); mainLayout->addWidget(bottomRightGroupBox, 2, 1); mainLayout->addWidget(progressBar, 3, 0, 1, 2); mainLayout->setRowStretch(1, 1); mainLayout->setRowStretch(2, 1); mainLayout->setColumnStretch(0, 1); mainLayout->setColumnStretch(1, 1); setLayout(mainLayout); setWindowTitle(tr("Styles")); changeStyle("NorwegianWood"); } В заключение мы помещаем дочерний виджет в компоновщик. void WidgetGallery::changeStyle(const QString &styleName) { if (styleName == "NorwegianWood") { QApplication::setStyle(new NorwegianWoodStyle); } else { QApplication::setStyle(QStyleFactory::create(styleName)); } changePalette(); } Когда пользователь выбирает стиль в выпадающем списке, мы вызываем QApplication::setStyle(), чтобы динамически изменить стиль приложения. void WidgetGallery::changePalette() { if (useStylePaletteCheckBox->isChecked()) QApplication::setPalette(QApplication::style()->standardPalette()); else QApplication::setPalette(originalPalette); } Если пользователь включает Use style's standard palette, то используется текущий стиль стандартной палитры; в противном случае применяется палитра по умолчанию системы. Для стиля Norwegian Wood это не имеет никакого значения, поскольку мы всегда заменяем палитру нашей собственной палитрой в NorwegianWoodStyle::polish(). void WidgetGallery::advanceProgressBar() { int curVal = progressBar->value(); int maxVal = progressBar->maximum(); progressBar->setValue(curVal + (maxVal - curVal) / 100); } Слот advanceProgressBar() вызывается с регулярным интервалом для обработки индикатора выполнения. Так как нам не известно, как долго пользователь будет находиться в программе Styles, мы воспользовались логарифмической формулой: чем ближе приближается отметка индикатора выполнения к 100%, тем медленнее обработка. Мы рассмотрим createProgressBar() сейчас. void WidgetGallery::createTopLeftGroupBox() { topLeftGroupBox = new QGroupBox(tr("Group 1")); radioButton1 = new QRadioButton(tr("Radio button 1")); radioButton2 = new QRadioButton(tr("Radio button 2")); radioButton3 = new QRadioButton(tr("Radio button 3")); radioButton1->setChecked(true); checkBox = new QCheckBox(tr("Tri-state check box")); checkBox->setTristate(true); checkBox->setCheckState(Qt::PartiallyChecked); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(radioButton1); layout->addWidget(radioButton2); layout->addWidget(radioButton3); layout->addWidget(checkBox); layout->addStretch(1); topLeftGroupBox->setLayout(layout); } Функция createTopLeftGroupBox() создает QGroupBox, который занимает верхний левый угол в WidgetGallery. Мы пропустим функции createTopRightGroupBox(), createBottomLeftTabWidget() и createBottomRightGroupBox(), которые очень похожи. void WidgetGallery::createProgressBar() { progressBar = new QProgressBar; progressBar->setRange(0, 10000); progressBar->setValue(0); QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(advanceProgressBar())); timer->start(1000); } В createProgressBar() мы создаем QProgressBar внизу WidgetGallery и подсоединяем сигнал timeout() к слоту advanceProgressBar(). |
Попытка перевода Qt документации. Если есть желание присоединиться, или если есть замечания или пожелания, то заходите на форум: Перевод Qt документации на русский язык... Люди внесшие вклад в перевод: Команда переводчиков |