简体   繁体   English

如何在QGroupBox标题中添加图标?

[英]How to add an icon to a QGroupBox title?

Is it possible to add an icon (programmatically, via QtCreator, with or without a stylesheet) to the QGroupBox title? 是否可以在QGroupBox标题中添加图标(通过QtCreator以编程方式,带有或不带有样式表)?

I want to place a mark close to the title of some of the QGroupBoxes in my GUI. 我想在GUI中靠近某些QGroupBoxes的标题放置一个标记。 The best place would be to the right of the title, but any other reasonable position (to the left of the title, or in the top right corner of the widget) could be also valid. 最佳位置将在标题的右侧,但任何其他合理位置(在标题的左侧,或在小部件的右上角)也可能有效。

The only way I could think of is creating a QLabel with an icon and visually placing it on top of the QGroupBox, in the desired position. 我唯一想到的方法是创建一个带有图标的QLabel,然后将其可视地放置在QGroupBox顶部的所需位置。 But I find this an ugly solution. 但是我发现这是一个丑陋的解决方案。

Edit 编辑

I know there is a way of setting the indicator used for checkable QGroupBoxes, as any image, both for checked and unchecked states, using stylesheets. 我知道有一种方法可以使用样式表将用于可检查 QGroupBoxes的indicator设置为任何图像,包括已检查状态和未检查状态的任何图像。 But then the QGroupBox must be checkable, etc. I want to add this mark (a small image) independently to the checkability of the QGroupBox. 但是然后QGroupBox必须是可检查的,等等。我想将此标记(小图像)独立地添加到QGroupBox的可检查性中。

Background 背景

Unfortunatelly, QGroupBox does not have a setIcon method, as QPushButton does. 不幸的是, QGroupBox没有setIcon方法,就像QPushButton一样。

A possible solution could be to make QGroupBox checkable using QGroupBox::setCheckable and set a custom image as an indicator using a stylesheet like this: 可能的解决方案是使用QGroupBox::setCheckable使QGroupBox可检查,并使用QGroupBox::setCheckable 样式表将自定义图像设置为指示符:

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

However, this will make the whole group box disabled, when the checkbox is unchecked. 但是,如果取消选中该复选框,则会禁用整个组框。

Solution

Having this background in mind, I would suggest you a fairly complex, but also a pretty flexible solution, consisting of the following steps: 考虑到这种背景,我建议您一个相当复杂但又非常灵活的解决方案,包括以下步骤:

  1. Subclass QStyleOptionGroupBox and declare additional variables as public class attributes: 子类QStyleOptionGroupBox并将其他变量声明为公共类属性:

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

    These will be used for passing the decoration pixmap, as well as the placement settings, to the style. 这些将用于将装饰像素图以及放置设置传递给样式。

  2. Subclass QCommonStyle and reimplement QCommonStyle::drawComplexControl like this: 子类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. Subclass QGroupBox and reimplement QGroupBox::paintEvent like this: 子类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); 

Note: This solution does not work well when the group box is checkable. 注意:当可选中组框时,此解决方案不能很好地工作。

Example

The solution requires a lot of work, but fortunatelly I have created the necessary classes for you, as well as a complete example of how to use them in your own projects. 该解决方案需要大量工作,但是幸运的是,我已经为您创建了必要的类,以及如何在您自己的项目中使用它们的完整示例。 The code is available on GitHub . 该代码可在GitHub上获得

Result 结果

The provided example produces the following result: 提供的示例产生以下结果:

带有装饰的组框和单选按钮的窗口

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM