The following shows an attempt that is based on reading the style code. The result is not great, and for different styles will look worse. Styles should report the position of those rectangles through an implementation of subElementRect rather than calculate them in the rendering code using internal margin values etc.
class MenuItemWidget : public QWidget
{
public:
MenuItemWidget(QWidgetAction *action, QMenu *menu)
: QWidget(0), m_action(action), m_menu(menu)
{
}
~MenuItemWidget()
{
}
QSize sizeHint() const
{
return QSize(1, 50);
}
protected:
void paintEvent(QPaintEvent *event)
{
qDebug() << "painting";
QPainter painter(this);
const QStyle *menuStyle = m_menu->style();
const QString shortCutText = m_action->shortcut().toString();
QStyleOptionMenuItem option;
option.initFrom(m_menu);
option.rect = QRect(0, 0, width(), height());
option.checkType = m_action->isCheckable() ?
(m_action->actionGroup() ? QStyleOptionMenuItem::Exclusive : QStyleOptionMenuItem::NonExclusive)
: QStyleOptionMenuItem::NotCheckable;
option.checked = m_action->isChecked();
option.font = m_action->font();
option.fontMetrics = QFontMetrics(option.font);
option.icon = m_action->icon();
option.text = "\t" + shortCutText;
option.menuRect = m_menu->rect();
option.menuItemType = QStyleOptionMenuItem::Normal;
option.tabWidth = option.fontMetrics.width(shortCutText);
option.state = 0;
if (testAttribute(Qt::WA_UnderMouse))
option.state |= QStyle::State_Selected;
if (m_action->isEnabled())
option.state |= QStyle::State_Enabled;
menuStyle->drawControl(QStyle::CE_MenuItem, &option, &painter, this);
// trying to calculate the contents rect... it's not possible
QRect iconRect = QRect(QPoint(0,0), option.icon.actualSize(size()));
iconRect.moveTop((height() - iconRect.height()) / 2);
painter.fillRect(iconRect, QColor(200, 0, 0, 100));
QRect shortCutRect = QRect(width() - option.tabWidth, 0, option.tabWidth, height());
painter.fillRect(shortCutRect, QColor(0, 200, 0, 100));
QRect contentsRect = QRect(iconRect.topRight(), shortCutRect.bottomLeft());
contentsRect.setTop(0);
painter.fillRect(contentsRect, QColor(0, 0, 200, 100));
}
void enterEvent(QEvent *e)
{
update();
}
void leaveEvent(QEvent *e)
{ update(); }
private:
QWidgetAction *m_action;
QMenu *m_menu;
};