该小项目实现的功能很简单,如下图:
我使用的是vs2008+qt4.8.6调试Debug和Release都可运行。
通过继承QWidget,重写enterEnvent、leaveEvent和paintEvent事件来模拟动态按钮。通过该小例子可以学到:1、对QWidget一些事件的重写;2、对Qt设计师的熟悉;3、初步接触qt动画。
重要部分如下:
首先先看看头文件:我们在头文件除了声明了我们要重写的事件外,还声明了一些信号槽。其中的公共槽是为了传入图片和文字。私有槽是响应鼠标进入和离开的valueChanged信号。通过实现以下几个函数就能实现上述功能。
了解了头文件以后,我们就来看看cpp文件的函数定义:
这是进入事件的定义。在进入事件当中我们只需要将图片的大小恢复为原大小再start动画即可。我这里稍微缩小了一下图片大小,是因为在实际情况当中,图片原来大小较大,会超出主界面。
void MyWidgetButton::enterEvent(QEvent *)
{
m_bEnter = true;
m_bLeave = false;
//限制一下大小,进入的时候图片有点大
m_iPixWidth = m_iPixWidth - 25;
m_iPixHeight = m_iPixHeight - 25;
m_enterAnimation->start();
}
然后再看看离开事件,图片的原大小我是使用了两个int类型变量储存起来的。离开事件发生后就将原图片恢复到原来大小再start动画。
void MyWidgetButton::leaveEvent(QEvent *)
{
m_bEnter = false;
m_bLeave = true;
//因为enterEvent减小了图片,所以这儿必须重新把图片大小恢复,不然会越来越小
m_iPixWidth = m_iOldPixWidth;
m_iPixHeight = m_iOldPixHeight;
m_leaveAnimation->start();
}
接下里是绘画事件。绘画事件首要做的既是将图片大小变化为m_iTargetWidth、m_iTargetHeight。我们会在信号槽当中去定义它们的大小以达到图片的大小变换。图片尺寸变换完成以后就绘制图片和文字。
void MyWidgetButton::paintEvent(QPaintEvent *)
{
if(m_strImagePath.isEmpty())
{
return;
}
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); //QPainter::Antialiasing:反锯齿
QPixmap pixmap(m_strImagePath);
//scaled:图片自适应窗口
//Qt::IgnoreAspectRatio:不保持图片的长宽比
//Qt::SmoothTransformation:双线性滤波
pixmap = pixmap.scaled(m_iTargetWidth, m_iTargetHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
if(m_bEnter || m_bLeave)
{
int pixX = rect().center().x() - m_iTargetWidth / DIVISIONWIDGET;
int pixY = rect().center().y() - m_iTargetHeight / DIVISIONWIDGET - LIFTHIGHT;
QPoint point(pixX, pixY);
painter.drawPixmap(point, pixmap);
painter.drawText(QRectF(0, height()-20, width(), 20), Qt::AlignCenter, m_strText);
}
}
然后是鼠标的进入和离开槽函数:这两个函数的唯一作用即为改变target的尺寸以达到缩放图片的目的。
void MyWidgetButton::SltEnterImageChanged(QVariant index)
{
int i = index.toInt();
m_iTargetWidth = m_iPixWidth + i * 5;
m_iTargetHeight = m_iPixHeight + i * 5;
update();
}
void MyWidgetButton::SltLeaveImageChanged(QVariant index)
{
int i = index.toInt();
m_iTargetWidth = m_iPixWidth - i * 5;
m_iTargetHeight = m_iPixHeight - i * 5;
update();
}
最后的两个槽为获取图片和文字:获取到图片以后,根据图片得到尺寸信息。
void MyWidgetButton::SltSetImage(QString strImagePath)
{
m_strImagePath = strImagePath;
QPixmap pixmap(strImagePath);
m_iPixWidth = pixmap.width();
m_iPixHeight = pixmap.height();
m_iOldPixWidth = m_iPixWidth;
m_iOldPixHeight = m_iPixHeight;
m_iTargetWidth = m_iPixWidth - 25;
m_iTargetHeight = m_iPixHeight - 25;
//更新小部件,除非禁用了更新或隐藏了小部件
update();
}
void MyWidgetButton::SltSetText(QString strText)
{
m_strText = strText;
update();
}
需要源代码请到https://download.csdn.net/download/dzhongjie/11096374下载。我本意是上传源代码设置为0积分下载。奈何现在已经不能自己设置下载积分了。才知csdn现在如此的不厚道。
没有积分的同仁可发邮箱至[email protected]索取。