Как добавить значок в заголовок QGroupBox? - PullRequest
0 голосов
/ 03 октября 2018

Можно ли добавить значок (программно, через QtCreator, с таблицей стилей или без нее) к заголовку QGroupBox?

Я хочу поместить отметку рядом с заголовком некоторых из QGroupBoxes в моемGUI.Лучшее место было бы справа от заголовка, но любая другая разумная позиция (слева от заголовка или в верхнем правом углу виджета) также может быть действительной.

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

Редактировать

Я знаю, что есть способ установки indicator, используемый для проверяемых QGroupBoxes,как любое изображение, как для отмеченных, так и непроверенных состояний, используя таблицы стилей.Но тогда QGroupBox должен быть проверяемым и т. Д. Я хочу добавить эту отметку (маленькое изображение) независимо к проверяемости QGroupBox.

1 Ответ

0 голосов
/ 03 октября 2018

Фон

К сожалению, QGroupBox не имеет метода setIcon, как QPushButton.

Возможным решением может быть проверка QGroupBox с помощью QGroupBox::setCheckable и установите пользовательское изображение в качестве индикатора, используя таблицу стилей , например, так:

QGroupBox::indicator:unchecked {
    image: url(:/images/checkbox_unchecked.png);
}

Однако при отключении этого флажка вся группа будет отключена.не проверяется.

Решение

Имея в виду этот фон, я бы предложил вам довольно сложное, но и довольно гибкое решение, состоящее из следующих шагов:

  1. Подкласс QStyleOptionGroupBox и объявить дополнительные переменные в качестве атрибутов открытого класса:

    QPixmap pixmap;
    int offset;
    int leftSpace;
    int rightSpace;
    

    Они будут использоваться для передачи растрового изображения, а также параметров размещения,к стилю.

  2. Подкласс QCommonStyle и переопределение QCommonStyle::drawComplexControl вот так:

    if (const StyleOptionDecoratedGroupBox *groupBox = qstyleoption_cast<const StyleOptionDecoratedGroupBox *>(opt)) {
        QRect textRect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, widget);
        QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox, widget);
        int decorationOffset = 0;
        int pixmapRectWidth = 0;
        int pixmapHeight = 0;
        int textOffset = 0;
    
        if (!groupBox->pixmap.isNull()) {
            decorationOffset = groupBox->offset;
            pixmapRectWidth = groupBox->leftSpace
                            + groupBox->pixmap.width()
                            + groupBox->rightSpace;
            pixmapHeight = groupBox->pixmap.height();
            textOffset = decorationOffset + pixmapRectWidth;
        }
    
        textRect.adjust(textOffset, 0, textOffset, 0);
    
        // Draw frame
        if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
            QStyleOptionFrame frame;
            frame.QStyleOption::operator=(*groupBox);
            frame.features = groupBox->features;
            frame.lineWidth = groupBox->lineWidth;
            frame.midLineWidth = groupBox->midLineWidth;
            frame.rect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxFrame, widget);
            p->save();
            QRegion region(groupBox->rect);
            if (!groupBox->text.isEmpty()) {
                bool ltr = groupBox->direction == Qt::LeftToRight;
                QRect finalRect;
                if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) {
                    finalRect = checkBoxRect.united(textRect);
                    finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0);
                } else {
                    finalRect = textRect;
                }
                region -= finalRect;
            }
            p->setClipRegion(region);
            proxy()->drawPrimitive(PE_FrameGroupBox, &frame, p, widget);
            p->restore();
        }
    
        // Draw icon
        if (!groupBox->pixmap.isNull()) {
            p->fillRect(decorationOffset, 0, pixmapRectWidth, pixmapHeight, opt->palette.window().color());
            proxy()->drawItemPixmap(p, QRect(decorationOffset, 0, pixmapRectWidth, pixmapHeight),
                                    Qt::AlignCenter, groupBox->pixmap);
        }
    
        // Draw title
        if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
            QColor textColor = groupBox->textColor;
            if (textColor.isValid())
                p->setPen(textColor);
            int alignment = int(groupBox->textAlignment);
            if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, opt, widget))
                alignment |= Qt::TextHideMnemonic;
            proxy()->drawItemText(p, textRect,  Qt::TextShowMnemonic | Qt::AlignHCenter | alignment,
                                  groupBox->palette, groupBox->state & State_Enabled, groupBox->text,
                                  textColor.isValid() ? QPalette::NoRole : QPalette::WindowText);
            if (groupBox->state & State_HasFocus) {
                QStyleOptionFocusRect fropt;
                fropt.QStyleOption::operator=(*groupBox);
                fropt.rect = textRect;
                proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
            }
        }
    } else {
        QCommonStyle::drawComplexControl(cc, opt, p, widget);
    }
    
  3. ПодклассQGroupBox и переопределение QGroupBox::paintEvent вот так:

    CustomStyle style;
    QPainter painter(this);
    StyleOptionDecoratedGroupBox option;
    
    initStyleOption(&option);
    option.pixmap = m_pixmap;
    option.offset = m_offset;
    option.leftSpace = m_leftSpace;
    option.rightSpace = m_rightSpace;
    
    style.drawComplexControl(QStyle::CC_GroupBox, &option, &painter, this);
    

Примечание: Это решение не работает, когда флажок группы установлен.

Пример

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

Результат

Приведенный пример дает следующий результат:

Window with a decorated group box and radio buttons

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...