Перевод сопроводительной записки к примеру из документации "Style" |
Здравствуйте, гость ( Вход | Регистрация )
Перевод сопроводительной записки к примеру из документации "Style" |
Гость_Hrundel_* |
5.10.2012, 20:47
Сообщение
#1
|
Гости |
ссылка на оригинал: http://doc.crossplatform.ru/qt/4.5.0/widgets-styles.html Перевод требует некоторого редактирования. Пример "Styles" иллюстрирует, как создать пользовательские стили прорисовки виджета используя Qt, а также демонстрирует преднастроенные стили Qt. Стиль в Qt является подклассом QStyle или одного из его подклассов. Стили выполняют прорисовку на поверхности виджета. Qt обеспечивает предоставление всего спектра предопределенных стилей, как встроенных в QtGui библиотеку, так и находящихся в плагинах. Заказные стили обычно создаются путем наследования одного из существующих стилей и переопределением некоторых виртуальных функций. В данном примере, заказной стиль называется NorwegianWoodStyle и наследуется от QMotifStyle. Его основными особенностями являются текстуры дерева используемые для заполнения большинства виджетов, закругленные кнопки и ромбовидные комбо-боксы. Для реализации стиля, мы используем несколько передовых особенностей предоставляемых QPainter, таких как сглаживание (для получения плавных углов кнопок), использование альфа каналов (для создания у кнопок эффекта вдавливания или выпуклости), и рисования линий (для заливки кнопок и рисования линий). Мы так же будем использовать множество возможностей классов QBrush и QPalette. Пример состоит из следующих классов: NorwegianWoodStyle наследуется от QMotifStyle и реалезует стиль Norwegian Wood. WidgetGallery является подклассом QDialog, который показывает большинство главных виджетов и позваляет пользователю переключать стили динамически. Определение класса 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); }; Все функции объявленые как public, декларированы в QStyle (QMotifStyle исходный класс) и переопределены здесь для перезаписи вида и заполнения Motif. Функции объявленные как private являются вспомогательными. Реализация класса 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 и адаптирует палитру для подгонки стиля. В основном стили не нуждаются в переопределении этой функции. NorwegianWoodStyle переопределяет эту функцию для создания «деревянной» палитры. Мы начинаем с определения некоторых необходимых экземпляров QColors. Потом читаем два файла с изображением текстуры дерева в формате PNG. Префиксы в пути файла указывают на то, что файлы являются внедренными ресурсами woodbackground.png Данная текстура используется для большинства виджетов. Рисунок дерева горизонтальный. woodbutton.png Данная текстура используется для заполнения кнопок и комбо-боксов. Рисунок дерева вертикальный и более контрастный чем текстура используемая для заднего плана. Переменная midImage инициализирована так, чтобы являться клоном buttonImage, но потом мы используем QPainter и заполняем его черным цветом с 25% прозрачности (черный цвет со значением альфа канала 65). В результате получается несколько более темное изображение нежели в 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() объявлена как private и устанавливает текстуры для определенных цветовых ролей, резервирую существующий цвет в QBrush. QBrush может содержать как сплошные цвета так и текстуры одновременно. Сплошные цвета используются для рисования текста и других графических элементов, в которых текстуры были бы излишни или смотрелись бы плохо. Наконец, мы устанавливаем кисть для группы недоступных цветов палитры. Мы используем woodbackground.png в качестве текстуры для всех недоступных виджетов, включая кнопки, и темный цвет для приглушения текстуры (как у кнопки Toggle Push Button). Давайте перейдем к другим функциям, переопределяемым от 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(). В идеале, мы должны бы помнить оригинальное состояние каждого виджета и восстанавливать его в 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 в качестве ширины поля вокруг комбо-бокса, таким образом обеспечивая достаточное количество места вокруг текста и стрелки для скругленных углов. Значение по умолчанию для MotifStyle равно 2. Мы также меняем параметры QScrollBars, высоту горизонтального скрола, и ширину вертикального скрола на 4 пиксела больше чем в MotifStyle. Это предаст стилю большую отличительность. Для всех других элементов 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 дает прямоугольник, в котором рисуется элемент примитива. Параметр parametr является объектом QPainter, который мы можем использовать для рисования на виджете. Параметр widget является собственно самим виджетом. Обычно, вся информация, которая нам нужна, доступна в option и painter, поэтому в widget нет необходимости. Мы можем использовать его для исполнения специальных эффектов, на пример, QMacStyle использует его для анимации кнопок по умолчанию. Если вы будете его использовать - знайте, что вызывающая процедура допускает присвоение нулевого указателя. Мы начинаем с определения трех QColor, которые понадобятся позже. Кроме того, мы поместим x, y ширину и высоту прямоугольного компонента виджета в локальные переменные. Значение использованное для 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() объявлена как privatе, мы вернемся к ней позже. 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, и инициализируем их на базе статуса кнопки: Если кнопка является плоской, мы используем кисть фона. Мы устанавливаем darker в true, если кнопка нажата или вдавлена. Если кнопка в текущем состоянии нажата и удерживается пользователем или во вдавленном состоянии, мы используем Mid компонент палитры. Мы устанавливаем darker в true, если кнопка вдавлена. В других случаях, мы используем кнопку компонент из палитры. Следующий скрин иллюстрирует как QPushButton прорисовывают основные свои основные состояния. Для определения является ли кнопка плоской или нет, нам необходимо сбросить параметры option в QStyleOptionButton и проверить специфицирован ли флаг 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() для рисования этой же области, но уже полупрозрачным черным цветом для затемнения если 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 на полученые правильные результаты. На десктопах справа налево, освещение падает справа сверху соответственно. Самый простой путь протестировать как будет выглядеть стиль в таком освещении запустить программу из командной строки добавив опцию –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. Другие примитивные элементы обрабатываются базовым стилем. Давайте теперь вернемся к другим функциям: 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() объявлена как private, что устанавливает компонент текстуры QBrush в определенную цветовую роль, для всех цветовых групп (активной, неактивной, недоступной). Мы будем использовать ее для инициализации палитры в 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() объявлена как private и создает объект QPainterPath для скругленных кнопок. Кривая содержит восемь сегментов: четыре arc сегмента для углов и четыре лини для сторон. Приблизительно 250 строк кода, и мы получили полнофункциональный стиль базирующийся на предопределенных стилях. Собственные стили могут быть использованы для создания более ясного вида приложения. Класс WidgetGallery В довершение, мы быстро рассмотрим класс WidgetGallery, который содержит большинство главных Qt виджетов и позволяет пользователю менять стили динамически. Определение класса WidgetGallery: 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...() объявлены как private и настраивают различные элементы WidgetGallery. connect(styleComboBox, SIGNAL(activated(const QString &)), this, SLOT(changeStyle(const 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», используется текущий стиль стандартной палитры. void WidgetGallery::advanceProgressBar() { int curVal = progressBar->value(); int maxVal = progressBar->maximum(); progressBar->setValue(curVal + (maxVal - curVal) / 100); } Слот advanceProgressBar() вызывается с регулярным интервалом для обработки progress bar. Так как нам не известно как долго пользователь будет выполнять программу, мы воспользовались логоритмической формулой: Чем ближе приблежается отметка прогресс-бара к 100%, тем медленее обработка. Рассмотрим этот момент. 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(). На этом все. Удачи. |
|
|
iReset |
6.10.2012, 19:14
Сообщение
#2
|
Участник Группа: Участник Сообщений: 178 Регистрация: 6.6.2012 Пользователь №: 3414 Спасибо сказали: 23 раз(а) Репутация: 2 |
Спасибо за перевод. Внесу его в память перевода.
|
|
|
Текстовая версия | Сейчас: 22.11.2024, 6:28 |