在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

QAbstractItemView为截断的项显示ToolTip(使用事件过滤)的更多相关文章

  1. QAbstractItemView为截断的项显示ToolTip(在eventFilter函数里覆盖QEvent::ToolTip事件)

    在Qt中想要为QAbstractItemView中长度不够而使得内容被截断的项显示ToolTip,Qt官网有一篇文章介绍使用事件过滤器来显示太长的项,但是没有涵盖图标的情况.显示列头项太长的情况等等, ...

  2. css截断长文本显示

    实现 截断长文本显示处理,以前是通过后台的截取,但这种方法容易丢失数据,不利于SEO. 而通过前端css的截断,则灵活多变,可统一运用与整个网站. 这项技术主要运用了text-overflow属性,这 ...

  3. 在Winfrom 中,如何实现combox 的列表自动显示ToolTip提示 ?

    //带ToolTip的combox类文件 public class ComboBoxWithTooltip : ComboBox { //tipProperty为显示ToolTip文本的数据源的属性 ...

  4. C++ CEF 浏览器中显示 Tooltip(标签中的 title 属性)

    在 Windows 中将 CEF 集成到 C++ 客户端以后,默认是无法显示 tooltip 的,比如图片标签中的 title 属性. 实现的方式其实很简单,按下面的步骤操作就可以: 创建一个文本文件 ...

  5. 【UWP】仅在TextBlock文本溢出时显示Tooltip

    前言 这是我今天在回答SO问题时偶然遇到的,觉得可能还比较通用,就记录下来以供参考. 通常,我们使用ToolTip最简单的方式是这样: <TextBlock Text="Test&qu ...

  6. dotnet ef执行报错, VS 2019发布时配置项中的Entity Framework迁移项显示不出来

    VS 2019发布时配置项中的Entity Framework迁移项显示不出来 dotnet ef dbcontext list --json “无法执行,因为找不到指定的命令或文件.可能的原因包括: ...

  7. WPF drag过程中显示ToolTip.

    原文:WPF drag过程中显示ToolTip. 在drag/drop过程中,我们在判断出over的元素上是否可以接受drag的东西之后,通常是通过鼠标的样式简单告诉用户这个元素不接受现在drag的内 ...

  8. ListView控件的列表项的文字不满一行的时候,如何实现点击该列表项的空白区域仍可触发列表项的点击事件

    今天在做Demo的过程中,使用到了ListView.然而在实现过程中,发现一个出现了一个问题:只能点击列表项的文字区域可以触发点击事件,而点击列表项的空白区域无法触发点击事件. 如下图: listit ...

  9. NGUI---使用脚本控制聊天系统的内容显示,输入事件交互

    在我的笔记Unity3D里面之 简单聊天系统一 里面已经介绍怎么创建聊天系统的背景.给聊天系统添加滚动条,设置Anchor锚点.以及设计聊天系统的输入框. 效果图如下所示: 现在我们要做的就是使用脚本 ...

随机推荐

  1. fusionchart实现ZoomLine 资源 破解版 出口能力

    最近的曲线需要用油画ZoomLine官方网站看了好几天,今天整理出来供大家参考使用 zoomline.html资源 <!DOCTYPE HTML PUBLIC "-//W3C//DTD ...

  2. TensorFlow 学习(十一)—— 正则(regularizer)

    正则作用的对象是目标函数,如图对均方误差使用 ℓ2 正则: loss = tf.reduce_mean(tf.square(y-y_) + tf.contrib.layers.l2_regulariz ...

  3. 【u253】售货厅

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 售票厅出售关于音乐会的票,取代原来的卖一张票的形式,而是一组座号连续的票.售票室已经收到很多预订.每个 ...

  4. Struts2——(4)OGNL与struts标签

    一.OGNL Object Graphic Navigation Language  对象图导航语言 依赖于 ognl.jar包 OGNL不是Struts框架独有的,它是和框架独立的一种技术. 例如: ...

  5. WPF 使用 SharpDX 在 D3DImage 显示

    原文:WPF 使用 SharpDX 在 D3DImage 显示 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://linde ...

  6. wpf mvvm datagrid数据过滤

    原文:wpf mvvm datagrid数据过滤 datagrid数据过滤,你可以通过设置RowStyle属性,通过将Visibility绑定到ViewModel层的属性来控制是否可见,比如:   & ...

  7. 《冰球撞击》Android休闲桌球类游戏现已面试,快来下载吧!

    <冰球撞击>Android休闲桌球类游戏现已完工上市快来下载吧! http://pan.baidu.com/s/1dD9vIRv <冰球撞击>是一个类似玩投篮机操作方式的And ...

  8. WPF进阶教程 - 使用Decorator自定义带三角形的边框

    原文:WPF进阶教程 - 使用Decorator自定义带三角形的边框 写下来,备忘. Decorator,有装饰器.装饰品的意思,很容易让人联想到设计模式里面的装饰器模式.Decorator类负责包装 ...

  9. WPF 使用字体引发的 CLR20r3 问题排查

    开发机器上运行完好,拷贝置目标机器上出现此问题 问题排查: 计算机-->管理-->事件查看器--->windows日志-->应用程序 Application Error  看不 ...

  10. 『开发技巧』Python音频操作工具PyAudio上手教程

    『开发技巧』Python音频操作工具PyAudio上手教程 ​ 0.引子 当需要使用Python处理音频数据时,使用python读取与播放声音必不可少,下面介绍一个好用的处理音频PyAudio工具包. ...