QMenu中没有提供菜单弹出方向的参数,所以需要我们自行计算菜单位置。
先通过addAction把需要的菜单项目全部添加好,然后调用sizeHine获取菜单大小。
然后在exec里面计算出最后显示的位置即可。
QMenu的自绘可以通过重载paintEvent来实现,通过actionGeometry来得到每一项的位置, 然后根据类型进行绘制。
const QList<QAction*>& actions = pMenu->actions();
for (int i = 0; i < actions.size(); ++i)
{
QAction* pAction = actions.at(i);
QRect rect = pMenu->actionGeometry(pAction);
if (i == _hotItemIdx && !pAction->isSeparator())
{
drawFillStyle(*pPainter, _itemStyle[UIG_HOT], rect);
drawText(*pPainter, pAction->text(), _textStyle[UIG_HOT], rect);
}
else
{
drawFillStyle(*pPainter, _itemStyle[UIG_NORMAL], rect);
drawText(*pPainter, pAction->text(), _textStyle[UIG_NORMAL], rect);
}
if (pAction->isSeparator())
{
// draw seperator
}
else if (pAction->isCheckable())
{
// draw check style
}
else
{
// to do other type paint
}
if (pAction->menu())
{
QBrush brush;
brush.setStyle(Qt::SolidPattern);
brush.setColor(0xffcccccc);
QPainterPath path;
path.moveTo(QPointF(rect.right() - 2, rect.top() + rect.height() / 2));
path.lineTo(QPointF(rect.right() - 2 - 5, rect.top() + rect.height() / 2 - 5));
path.lineTo(QPointF(rect.right() - 2 - 5, rect.top() + rect.height() / 2 + 5));
path.closeSubpath();
pPainter->fillPath(path, brush);
}
}
菜单文字中遇到&需要额外进行分割合理,将带有&的文字换成下划线字体文字进行绘制。 通过qt的QFontMetrics来计算文字长度。
QFont font;
font.setPixelSize(textStyle._font.fontSize);
font.setFamily(textStyle._font.fontFamily);
font.setBold(textStyle._font.bold);
font.setItalic(textStyle._font.italic);
font.setUnderline(textStyle._font.underline);
QString text = item.data(USER_CONTENT).toString();
QStringList list = text.split("&");
int height = 0;
QFontMetrics fm(font);
if (list.size() > 1)
{
for (size_t i = 0; i < list.size(); i++)
{
int totalWidth = fm.width(list.at(i));
}
...
}