zoukankan      html  css  js  c++  java
  • Qt之实现360安全卫士主界面(三)

          这篇博文主要讲述360安全卫士工具栏的创建;工具栏由图片和文字组成,当鼠标移到工具栏按钮上时,需要有些特征表达该现象,如背景色变化等;当然鼠标单击工具栏按钮时,同样也要有些特征,并且这个特征区别于鼠标移到按钮上的特征;写起来有些拗口,我给大家先看看我实现的效果图。

          单击按钮时和鼠标移到按钮上时,按钮背景会不同,并且单击其他按钮时,已单击的那个按钮背景应该恢复。下面讲解其具体实现。

    一、工具栏的创建

          工具栏当然是自定义的部件了(继承于QWidget),工具栏上的那些按钮都是继承于QToolButton;其中有9个按钮,最右边的是label;工具栏类的成员变量如下所示:

    View Code
    QList<MyBtn*> m_listMyBtnPoint;//自定义按钮
    QList<QString> m_listMyStr;//按钮对应的文本
    QLabel *m_pLabel;//label,显示logo

          首先当然是创建这些子部件了,和一般的没啥区别:

    View Code
    //CreateWidget创建部件
    void ToolBar::CreateWidget()
    {
    //文本例子
    m_listMyStr<<"Examine"<<"KillTrojan"<<"CleanDust"<<"LeakRepair"<<"SysRepair"
    <<"CleanCom"<<"FunFull"<<"SoftMan"<<"OptSpeed";
    //创建toolbutton
    for(int nIndex = 0;nIndex<WIDGET_CNT;++nIndex)
    {
    //图像资源路径
    QString strImage = QString(":/image/%1.png").arg(nIndex+1);
    //创建自定义QToolButton(MyBtn)
    m_listMyBtnPoint.append(new MyBtn(strImage,m_listMyStr[nIndex],this));
    //设置toolbutton的位置
    m_listMyBtnPoint.at(nIndex)->move(nIndex*TOOLWIDGET_H+VALUE_DIS,0);
    //该信号槽设置其他按钮的按下状态bool值
    connect(m_listMyBtnPoint.at(nIndex),SIGNAL(signal_parent(void*)),this,SLOT(slot_set(void*)));
    }
    //创建label
    m_pLabel = new QLabel(this);
    m_pLabel->setPixmap(QPixmap(":/image/logo.png"));
    }

          工具栏里的按钮和label都是手动定位(即设置位置信息),所以重写了resizeEvent事件,在resizeEvent事件里进行部件定位,如下所示:

    View Code
    //resizeEvent
    void ToolBar::resizeEvent (QResizeEvent * event)
    {
    //按钮垂直居中
    m_pLabel->move(rect().width()-m_pLabel->pixmap()->width()-VALUE_DIS,(rect().height()-m_pLabel->pixmap()->height())/2);
    }

          大家可能会想:在resizeEvent事件里只对label进行定位了,那其他9个按钮了?因为其他9个按钮都是从最左边(也就是0)计算相对位移,而label是从最右边计算的,通过rect()函数获得工具栏的最右边位置信息;按钮在创建部件函数的时候就定位了位置,如果label也在那个时候定位位置的话是错误的,因为那是工具栏部件的大小是未知的,所以rect()函数返回的值也是未知的;当放在resizeEvent事件中进行处理时,工具栏部件显示出来的时候,其大小都是可以确定的。

    二、工具栏按钮效果设置

          工具栏按钮继承于QToolButton;首先是设置按钮的基本显示效果了,去掉Qt自带的效果;包括文本颜色,文本字体,样式大小等,这些在我前几篇的博文中有讲解;代码如下所示:

    View Code
    //构造函数
    MyBtn::MyBtn(const QString &strImage,const QString &strInfo,QWidget *parent):QToolButton(parent),
    m_bOver(false),m_bPress(false),m_strImage(strImage),m_strInfo(strInfo)
    {
    //文本颜色
    QPalette objPalette = palette();
    objPalette.setColor(QPalette::ButtonText, QColor(220,220,220));
    setPalette(objPalette);
    //文本粗体
    QFont &objFont = const_cast<QFont &>(font());
    objFont.setWeight(QFont::Bold);
    //样式
    setStyleSheet("QToolButton{border:0px;}");
    //大小
    setIconSize(QSize(TOOLICON_WH,TOOLICON_WH));
    resize(TOOLWIDGET_W,TOOLWIDGET_H);
    setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
    //设置图像文本
    setIcon(QPixmap(strImage));
    setText(strInfo);
    //连接press信号槽,表示按钮按下时
    connect(this,SIGNAL(pressed()),this,SLOT(slot_pressed()));
    }

          OK,按钮的基本效果就出来了,按钮是透明的,只显示图片和文本,没背景信息。
          再一步就是设置鼠标移到按钮上的效果了,鼠标移到按钮上时,背景呈现立体的半透明效果;当鼠标移上去时,设置移动标志(m_bOver)为ture,当鼠标离开按钮时,设置移动标志为false;然后各自update发出重绘事件请求即可。

    View Code
    //enterEvent--鼠标移到按钮上事件
    void MyBtn::enterEvent(QEvent *event)
    {
    SetOver(true);
    }
    //leaveEvent--鼠标离开按钮事件
    void MyBtn::leaveEvent(QEvent *event)
    {
    SetOver(false);
    }
    //SetOver
    void MyBtn::SetOver(bool bEnable)
    {
    if(bEnable!=m_bOver)
    {
    //设置m_bOver标志位
    m_bOver = bEnable;
    //更新
    update();
    }
    }

          在重绘事件里会对bOver进行判断来绘制鼠标移到按钮上的效果,后面讲解到重绘时再细节描述。

          然后就是鼠标单击按钮时的效果了,和鼠标移到按钮上的实现原理基本一样;不过只是在槽函数中而不是由事件触发了;信号和槽函数在构造函数中已经被连接上了,槽函数如下:

    View Code
    //slot_pressed--槽函数
    void MyBtn::slot_pressed()
    {
    SetPress(true);
    emit signal_parent(this);
    }

          其中SetPress函数即设置按下标志(m_bPress)然后发送重绘请求。

    View Code
    //SetPress
    void MyBtn::SetPress(bool bEnable)
    {
    if(bEnable!=m_bPress)
    {
    //设置m_bOver标志位
    m_bPress = bEnable;
    //更新
    update();
    }
    }

          其中slot_pressed槽函数中发送了一个自定义信号signal_parent,在工具栏部件中会对该信号进行连接,其中信号的参数为按钮对象的指针。工具栏部件连接该信号的槽函数为slot_set函数:

    View Code
    //槽函数
    void ToolBar:: slot_set(void *pObject)
    {
    for(int nIndex = 0;nIndex<WIDGET_CNT;++nIndex)
    {
    if(m_listMyBtnPoint.at(nIndex)!=pObject)
    {
    m_listMyBtnPoint.at(nIndex)->SetPress(false);
    }
    }
    }

          总体意思是:例如有A,B,C三个按钮在工具栏中,如果按下了A按钮,这是按下B按钮时,发送信号给工具栏,然后在工具栏对应的槽函数中进行指针值对比,如果不是B按钮,就调用其他对应按钮的SetPress函数,并设置为false,这样A按钮就没有按下去的背景效果了(排他性)。

    三、工具栏按钮效果绘制

          绘制当然要在按钮的paintEvent事件处理函数中实现了,代码如下所示,代码注释的很详细,我就不多说了:

    View Code
    //重绘事件
    void MyBtn::paintEvent(QPaintEvent *event)
    {
    QPainter painter(this);
    //如果按钮被按下
    if(m_bPress)
    {
    //绘制被按下时的效果
    painterinfo(150,200,&painter);
    }
    else if(m_bOver)//如果按钮没有被按下并且鼠标移到按钮上
    {
    //绘制鼠标移到按钮上的按钮效果
    painterinfo(50,100,&painter);
    }
    //调用基类的重绘事件以显示图像文本等
    QToolButton::paintEvent(event);
    }
    //绘制背景渐变
    void MyBtn::painterinfo(int nTopPartOpacity,int nBottomPartOpacity,QPainter *pPainter)
    {
    //设置画笔
    QPen objPen(Qt::NoBrush,1);
    pPainter->setPen(objPen);
    //设置渐变画刷
    QLinearGradient objLinear(rect().topLeft(),rect().bottomLeft());
    //顶部颜色和透明度
    objLinear.setColorAt(0,QColor(150,150,150,nTopPartOpacity));
    //中间颜色和透明度
    objLinear.setColorAt(0.5,QColor(50,50,50,255));
    //底部颜色和透明度
    objLinear.setColorAt(1,QColor(100,100,100,nBottomPartOpacity));
    QBrush objBrush(objLinear);
    pPainter->setBrush(objBrush);
    //画圆角矩形
    pPainter->drawRoundedRect(rect(),5,5);
    }

          OK,这篇博文就写完了,下一篇博文主要讲解标题栏和状态栏的构建了。

  • 相关阅读:
    STM32 F4 DAC DMA Waveform Generator
    STM32 F4 General-purpose Timers for Periodic Interrupts
    Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式
    Python第十三天 django 1.6 导入模板 定义数据模型 访问数据库 GET和POST方法 SimpleCMDB项目 urllib模块 urllib2模块 httplib模块 django和web服务器整合 wsgi模块 gunicorn模块
    查看SQL Server服务运行帐户和SQL Server的所有注册表项
    Pycharm使用技巧(转载)
    SQL Server 2014内存优化表的使用场景
    Python第十天 print >> f,和fd.write()的区别 stdout的buffer 标准输入 标准输出 从控制台重定向到文件 标准错误 重定向 输出流和输入流 捕获sys.exit()调用 optparse argparse
    Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数
    Python第六天 类型转换
  • 原文地址:https://www.cnblogs.com/appsucc/p/2417267.html
Copyright © 2011-2022 走看看