自定义QStyle的问题。详尽进贴~~
最近做多国语言,将中英文翻译成法语,西班牙语。翻译之后的法语和西班牙语的字符数太多(英文只有6个字符,法语变成了20个!!)。以前的QToolbutton的text不换行就完全显示不全了。现在想自己写一个支持字符数太多就换行的style,主要从QPlastiqueStyle的风格继承。
ToolButton的绘制在PaintEvent里面,过程如下
QStylePainter p(this);
QStyleOptionToolButton opt;
initStyleOption(&opt);
p.drawComplexControl(QStyle::CC_ToolButton, opt);
QStylePainter是QT提供的便利类。其实
p.drawComplexControl(QStyle::CC_ToolButton, opt);调用的还是这个style的drawComplexControl();对于CC_ToolButton这个匹配项(QStyle的枚举CC对应ComplexControl),QPlastiqueStyle,QWindowsStyle的drawComplexControl中都没有。最后在QCommonStyle中找到。
if (const QStyleOptionToolButton *toolbutton
= qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
QRect button, menuarea;
//返回subControl SC_Toolbutton的RECT
button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, widget);
menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
State bflags = toolbutton->state & ~State_Sunken;
if (bflags & State_AutoRaise) {
if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
bflags &= ~State_Raised;
}
}
State mflags = bflags;
if (toolbutton->state & State_Sunken) {
if (toolbutton->activeSubControls & SC_ToolButton)
bflags |= State_Sunken;
mflags |= State_Sunken;
}
QStyleOption tool(0);
tool.palette = toolbutton->palette;
if (toolbutton->subControls & SC_ToolButton) {
if (bflags & (State_Sunken | State_On | State_Raised)) {
tool.rect = button;
tool.state = bflags;
//按前面的状态判断绘制PE元素,Panel是面板的意思
proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
}
}
if (toolbutton->state & State_HasFocus) {
QStyleOptionFocusRect fr;
fr.QStyleOption::operator=(*toolbutton);
fr.rect.adjust(3, 3, -3, -3);
if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)
fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator,
toolbutton, widget), 0);
//获取焦点时focus区域的绘制
proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
}
//这一段应该就是字体大小和Label绘制的代码
QStyleOptionToolButton label = *toolbutton;
label.state = bflags;
int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);//这里使用的PM_DefaultFrameWidth,在这个枚举中没有找到特别为ToolButton定制的。
label.rect = button.adjusted(fw, fw, -fw, -fw);
proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
if (toolbutton->subControls & SC_ToolButtonMenu) {
tool.rect = menuarea;
tool.state = mflags;
if (mflags & (State_Sunken | State_On | State_Raised))
proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget);
} else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
QRect ir = toolbutton->rect;
QStyleOptionToolButton newBtn = *toolbutton;
newBtn.rect = QRect(ir.right() + 5 - mbi, ir.y() + ir.height() - mbi + 4, mbi - 6, mbi - 6);
proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
}
}
break;
进入drawControl的代码:(这是绘制Label的)
if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
QRect textRect = button->rect;
//这是是否要绘制"&P" as P(带下划线)
uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
if (!proxy()->styleHint(SH_UnderlineShortcut, button, widget))
tf |= Qt::TextHideMnemonic;
if (!button->icon.isNull()) {
//Center both icon and text
QRect iconRect;
QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
if (mode == QIcon::Normal && button->state & State_HasFocus)
mode = QIcon::Active;
QIcon::State state = QIcon::Off;
if (button->state & State_On)
state = QIcon::On;
QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
int labelWidth = pixmap.width();
int labelHeight = pixmap.height();
int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
if (!button->text.isEmpty())
labelWidth += (textWidth + iconSpacing);
iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
textRect.y() + (textRect.height() - labelHeight) / 2,
pixmap.width(), pixmap.height());
iconRect = visualRect(button->direction, textRect, iconRect);
tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
if (button->direction == Qt::RightToLeft)
textRect.setRight(iconRect.left() - iconSpacing);
else
textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing);
if (button->state & (State_On | State_Sunken))
iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
p->drawPixmap(iconRect, pixmap);
} else {
tf |= Qt::AlignHCenter;
}
if (button->state & (State_On | State_Sunken))
textRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
if (button->features & QStyleOptionButton::HasMenu) {
int indicatorSize = proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget);
if (button->direction == Qt::LeftToRight)
textRect = textRect.adjusted(0, 0, -indicatorSize, 0);
else
textRect = textRect.adjusted(indicatorSize, 0, 0, 0);
}
//这里绘制text
proxy()->drawItemText(p, textRect, tf, button->palette, (button->state & State_Enabled),
button->text, QPalette::ButtonText);
}
分析到这里,不知道怎么改啦。。。。。
解释下代码,或者提醒一下,有大神能帮助我撒!?
[解决办法]
分享一下解决方法呀,好让我们学习学习