前行之路还需前行

Keep Moving 、 Keep Coding 、 啦啦啦

Qt 之 QQ系统表情(二)

简述

继上篇Qt 之 QQ系统表情(一) 中我们实现了简单的表情框,但是还遗留了一个问题,虽然我们能够显示动态的表情,但是总不能让表情框中的每一个表情都动态显示吧(见下图一),这样的效果显然不是我们要的,真正要实现的是当鼠标悬浮在某个表情上才让他动态显示,其他的都显示为静态样式(见图二)。好了,话不多说,代码走起!

图一
图一


图二
图二

代码之路

为了实现这个效果呢,我也是用了很多方法,最后发现了两种方法来达到这个效果。
先看一下QTableWidget的信号:

这里写图片描述

信号到是不少,但是有帮助的信号也就这两信号:

void cellEntered(int row, int column)
This signal is emitted when the mouse cursor enters a cell. The cell is specified by row and column.
This signal is only emitted when mouseTracking is turned on, or when a mouse button is pressed while moving into an item.
简而言之,当鼠标进入tableWidget中某个单元格时会发出。但是只有在mouseTracking 设置为true时,或者在鼠标的一个键被按下的同时鼠标进入tableWidget中某个单元格的。


void itemEntered(QTableWidgetItem * item)
This signal is emitted when the mouse cursor enters an item. The item is the item entered.
This signal is only emitted when mouseTracking is turned on, or when a mouse button is pressed while moving into an item.
单看英文注释发现和cellEntered信号意思差不多,基本算是一字之差,一个是cell一个是item,区别就在这里,仔细看下图中的输出,可以看出在鼠标进入每个单元格的时候都会触发cellEntered信号,而itemEntered信号只有在鼠标进入一个设置了item的单元格中才会触发。

这里写图片描述


测试这两个信号之后发现并没有什么卵用,只有在鼠标慢慢从一个单元格移动到另一个单元格中才会触发,当鼠标快速从一个单元格移动到另一个时这两个信号时有时无,具体可以看下图(图一),所以这两个信号并没有帮助,其实主要是给item设置了cellWidget的原因,如果未设置widget这两个信号是完全可以捕捉到鼠标移动到哪一个单元格(见图二)。
图一
这里写图片描述
图二
这里写图片描述

也有网上说用void entered(const QModelIndex & index)这个信号,效果也如上信号。信号不行,说不定事件就可以呢,继承了QTableWidget类,并重写了mouseMoveEvent事件,结果还是因为给item设置了cellWidget,当鼠标移动到表情图标时根本不会触发mouseMoveEvent事件,既然这个不行就试试eventFilter去专门捕捉mouseMove这个事件,结果当鼠标在图标上移动时根本不会触发mouseMove事件,详情见下图。

bool MyEmotionWidget::eventFilter(QObject *obj, QEvent *event)
{
    //鼠标在图标上移动时输出当前事件
    qDebug() << event->type();
    return __super::eventFilter(obj, event);
}

这里写图片描述

好吧,信号不行,事件也不行,这可咋办。经历重重失败,机智的我最终灵机一动,我干脆不捕捉信号了,我直接通过获取当前鼠标的位置来确定鼠标进入哪一个item,这就靠QTableWidget中的itemAt方法。

QTableWidgetItem * QTableWidget::itemAt(const QPoint & point) const

Returns a pointer to the item at the given point, or returns 0 if point is not covered by an item in the table widget.

代码如下

bool MyEmotionWidget::eventFilter(QObject *obj, QEvent *event)
{
    // 获取当前鼠标的位置
    QPoint point = QCursor::pos() - this->pos();
    // 根据鼠标的位置获取item
    QTableWidgetItem* tableWidgetItem = ui.tableWidget->itemAt(point);
    if (tableWidgetItem != NULL)
    {
        //m_preRow 和 m_preColumn 分别保存了上一次鼠标进入的单元格在QTableWidget中的位置
        //如果当前进入的还是同一个则不进行停止动态显示
        if(m_preRow != tableWidgetItem->row() || m_preColumn != tableWidgetItem->column())
        {
            // 将上一次鼠标进入的单元格中的表情停止动态显示
            QLabel* preEmotion = (QLabel*)ui.tableWidget->cellWidget(m_preRow, m_preColumn);
            if (preEmotion != NULL)
            {
                QMovie* preMoive = preEmotion->movie();
                // 恢复到动态表情图片的第一帧
                preMoive->jumpToFrame(0);
                preMoive->stop();
            }
        }
        // 将当前鼠标所在的单元格表情开始动态显示,先获取QLabel,再获取QMoive
        QLabel* curEmotion = (QLabel*)ui.tableWidget->cellWidget(tableWidgetItem->row(), tableWidgetItem->column());
        if (curEmotion != NULL)
        {
            QMovie* curMoive = curEmotion->movie();
            curMoive->start();
            m_preRow = tableWidgetItem->row();
            m_preColumn = tableWidgetItem->column();
        }
    }

    return __super::eventFilter(obj, event);
}

效果图

这里写图片描述

虽然实现了这个效果,但是在eventFilter方法中去根据获取鼠标当前位置获取item并不是十分妥当,下一篇将介绍另外的方法。

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GoForwardToStep/article/details/52381772
文章标签: qt qq 表情
上一篇Qt 之 QQ系统表情(一)
下一篇Qt 之 QQ系统表情(三)
想对作者说点什么? 我来说一句

Qt 之实现 QQ系统表情窗口

2016年09月07日 267KB 下载

QQ2017默认表情包PNG

2017年02月17日 255KB 下载

2017最新QQ默认表情

2017年02月04日 259KB 下载

老版QQ原生表情gif动态

2017年10月01日 272KB 下载

常见QQ表情包js

2015年11月14日 494KB 下载

QQ表情功能实现

2012年06月19日 1.95MB 下载

QQ原创表情保存器

2013年09月09日 302KB 下载

Android开发仿QQ表情的实现

2014年10月30日 3.92MB 下载

没有更多推荐了,返回首页

关闭
关闭