在Qt中想要为QAbstractItemView中长度不够而使得内容被截断的项显示ToolTip,Qt官网有一篇文章介绍使用事件过滤器来显示太长的项,但是没有涵盖图标的情况、显示列头项太长的情况等等,这里做了下修改,以符合现在所需。
环境:Qt 5.1.0
atooltipper.h
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#ifndef ATOOLTIPPER_H
#define ATOOLTIPPER_H #include <QObject> class AToolTipper : public QObject { Q_OBJECT public: explicit AToolTipper(QObject *parent = 0); virtual bool eventFilter(QObject *, QEvent *); protected: bool headerViewEventFilter(QObject *, QEvent *); }; #endif // ATOOLTIPPER_H |
atooltipper.cpp
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
#include "atooltipper.h"
#include <QHelpEvent> #include <QAbstractItemView> #include <QHeaderView> #include <QTreeView> #include <QTableView> #include <QToolTip> AToolTipper::AToolTipper(QObject *parent) : QObject(parent) { } bool AToolTipper::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::ToolTip) { QAbstractItemView *view = qobject_cast<QAbstractItemView*>(obj->parent()); if (!view) { return false; } QHeaderView *headerView = qobject_cast<QHeaderView*>(view); if (headerView) { return headerViewEventFilter(obj, event); } QHelpEvent *helpEvent = static_cast<QHelpEvent*>(event); QPoint pos = helpEvent->pos(); QModelIndex index = view->indexAt(pos); if (!index.isValid()) { return false; } QString itemText = view->model()->data(index).toString(); // 图标处理 QSize iconSize(0, 0); QIcon icon = view->model()->data(index, Qt::DecorationRole).value<QIcon>(); if (!icon.isNull()) { QList<QSize> listSize = icon.availableSizes(); if (listSize.size() > 0) { iconSize.setWidth(listSize.at(0).width()); iconSize.setHeight(listSize.at(0).height()); } } // 计算列头高度 int headerHeight = 0; int headerWidth = 0; QTreeView *treeView = qobject_cast<QTreeView*>(view); if (treeView) { headerHeight = treeView->header()->height(); } else { QTableView *tableView = qobject_cast<QTableView*>(view); if (tableView) { headerHeight = tableView->horizontalHeader()->height(); headerWidth = tableView->verticalHeader()->width(); } } // 文本边距 const int textMargin = view->style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; const int iconMargin = iconSize.width() > 0 ? (view->style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1) : 0; QRect rect = view->visualRect(index); QRect textRect = rect.adjusted(textMargin + iconSize.width() + iconMargin * 2, 0, -textMargin, 0); //实际可用矩形 QFontMetrics fm(view->font()); int flags = view->model()->data(index, Qt::TextAlignmentRole).toInt(); QSize itemTextSize = fm.boundingRect(textRect, flags | Qt::TextLongestVariant | Qt::TextWordWrap, itemText).size(); if ((itemTextSize.width() > textRect.width() || itemTextSize.height() > textRect.height()) && !itemText.isEmpty()) { // 指定tip的限定矩形 rect.adjust(headerWidth, headerHeight, headerWidth, headerHeight); QToolTip::showText(helpEvent->globalPos(), itemText, view, rect); } else { QToolTip::hideText(); } return true; } return false; } bool AToolTipper::headerViewEventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::ToolTip) { QHeaderView *headerView = qobject_cast<QHeaderView*>(obj->parent()); if (!headerView) { return false; } QHelpEvent *helpEvent = static_cast<QHelpEvent*>(event); QPoint pos = helpEvent->pos(); int index = headerView->logicalIndexAt(pos); if (index < 0) { return false; } QString itemText = headerView->model()->headerData(index, headerView->orientation()).toString(); const int textMargin = headerView->style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; int rectWidth = headerView->sectionSize(index) - textMargin * 2; int rectHeight = headerView->sizeHint().height(); QFontMetrics fm(headerView->font()); int flag = headerView->model()->headerData(index, headerView->orientation(), Qt::TextAlignmentRole).toInt(); QSize itemTextSize = fm.size(flag, itemText); if ((itemTextSize.width() > rectWidth || itemTextSize.height() > rectHeight) && !itemText.isEmpty()) { QToolTip::showText(helpEvent->globalPos(), itemText, headerView); } else { QToolTip::hideText(); } return true; } return false; } |
使用示例:
1
2 |
tableView->viewport()->installEventFilter(new AToolTipper(tableView));
tableView->horizontalHeader()->viewport()->installEventFilter(new AToolTipper(tableView->horizontalHeader())); |
效果图:
参考资料:
1.Show_tooltips_for_long_entries_of_your_custom_model http://qt-project.org/wiki/Show_tooltips_for_long_entries_of_your_custom_model
2.Tooltips for truncated items in a QTreeView http://www.mimec.org/node/337
http://blog.csdn.net/akof1314/article/details/14504747