www.qt-ui.com 原创技术文章
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)); } ... }
更多详情请浏览