西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页编程开发其它知识 → Qt完美实现360安全卫士主界面标题栏

Qt完美实现360安全卫士主界面标题栏

前往专题相关软件相关文章发表评论 来源:西西整理时间:2012/3/28 22:08:10字体大小:A-A+

作者:佚名点击:1121次评论:0次标签: 360安全卫士

360安全卫士9.6 绿色精简版
  • 类型:360工具大小:34.1M语言:中文 评分:6.3
  • 标签:
立即下载

  这篇博文主要讲解360安全卫士标题栏的创建。关于标题栏,我想大家应该都非常熟悉了,其主要包括窗口关闭、最大化/还原、最小化等按钮;但是标题栏的这些按钮都是非常有特色的。

      在我写这篇博文之前,我就已经完成了类似360安全卫士标题栏的创建代码,在开始写代码时,我仔细想了想360安全卫士主界面标题栏的构建方法,它是自绘的还是贴图的?所以我特意在360论坛查了查它皮肤制作的方法,并在它的安装目录下的找到了这些按钮的特定图片(皮肤文件解压),即由贴图来做的。

      既然知道了构建方法,那么就用代码实现即可,我实现的效果图如下(初始界面是这样,标题栏的其他效果和360安全卫士的标题栏效果一样):

      标题栏也是自定义的部件(继承于QWidget),在这个自定义的部件里,你想实现啥功能都可以。

一、部件构建

      部件构建当然是创建子部件,设置子部件样式,给标题栏设置布局管理等,这些也都是很基础的。

      标题栏由三个QLabel和五个QToolButton组成,这五个QToolButton即为标题栏最右边的五个功能按钮,首先当然是创建这些子部件了。

//创建子部件
void TitleBar::CreateWidget()
{
    //图像标签--logo
    m_pLabelIcon = new QLabel(this);
    QPixmap objPixmap(":/image/360AboutLogo.png");
    m_pLabelIcon->setPixmap(objPixmap.scaled(TITLE_H,TITLE_H));
    //文本标签--标题
    m_pLabelTitle = new QLabel(this);
    m_pLabelTitle->setText(QString("360 Safe Guard V8.5"));
    //文本标签--样式版本
    m_pLabelVersion = new QLabel(this);
    m_pLabelVersion->setText(QString("Use Class Style"));
    //设置鼠标形状
    m_pLabelVersion->setCursor(Qt::PointingHandCursor);
    //按钮--更换皮肤
    m_pBtnSkin = new QToolButton(this);
    //设置初始图片
    SetBtnIcon(m_pBtnSkin,eBtnStateDefault,true);
    //按钮--菜单
    m_pBtnMenu = new QToolButton(this);
    SetBtnIcon(m_pBtnMenu,eBtnStateDefault,true);
    //按钮--最小化
    m_pBtnMin = new QToolButton(this);
    SetBtnIcon(m_pBtnMin,eBtnStateDefault,true);
    //按钮--最大化/还原
    m_pBtnMax = new QToolButton(this);
    SetBtnIcon(m_pBtnMax,eBtnStateDefault,true);
    //按钮--关闭
    m_pBtnClose = new QToolButton(this);
    SetBtnIcon(m_pBtnClose,eBtnStateDefault,true);
    //获得子部件
    const QObjectList &objList = children();
    for(int nIndex=0; nIndex<objList.count();++nIndex)
    {
        //设置子部件的MouseTracking属性
        ((QWidget*)(objList.at(nIndex)))->setMouseTracking(true);
        //如果是QToolButton部件
        if(0==qstrcmp(objList.at(nIndex)->metaObject()->className(),"QToolButton"))
        {
            //连接pressed信号为slot_btnpress
            connect(((QToolButton*)(objList.at(nIndex))),SIGNAL(pressed()),this,SLOT(slot_btnpress()));
            //连接clicked信号为slot_btnclick
            connect(((QToolButton*)(objList.at(nIndex))),SIGNAL(clicked()),this,SLOT(slot_btnclick()));
            //设置顶部间距
            ((QToolButton*)(objList.at(nIndex)))->setContentsMargins(0,VALUE_DIS,0,0);
        }
    }
}

      子部件创建完之后,就要设置这些子部件的基本样式了,我使用qss样式表对其进行样式设置,当然还有其他方法。

View Code

//设置子部件样式(qss)
void TitleBar::SetWidgetStyle()
{
    //设置标签的文本颜色,大小等以及按钮的边框
    setStyleSheet("QLabel{color:#CCCCCC;font-size:12px;font-weight:bold;}QToolButton{border:0px;}");
    //设置左边距
    m_pLabelTitle->setStyleSheet("margin-left:6px;");
    //设置右边距以及鼠标移上去时的文本颜色
    m_pLabelVersion->setStyleSheet("QLabel{margin-right:10px;}QLabel:hover{color:#00AA00;}");
}

      最后就是创建布局管理器,把这些子部件加入到布局管理器中,我使用水平布局管理器,如下代码所示:

View Code

//创建设置布局
void TitleBar::CreateLayout()
{
    //水平布局
    m_pLayout = new QHBoxLayout(this);
    //添加部件
    m_pLayout->addWidget(m_pLabelIcon);
    m_pLayout->addWidget(m_pLabelTitle);
    //添加伸缩项
    m_pLayout->addStretch(1);
    //添加部件
    m_pLayout->addWidget(m_pLabelVersion);
    m_pLayout->addWidget(m_pBtnSkin);
    m_pLayout->addWidget(m_pBtnMenu);
    m_pLayout->addWidget(m_pBtnMin);
    m_pLayout->addWidget(m_pBtnMax);
    m_pLayout->addWidget(m_pBtnClose);
    //设置Margin
    m_pLayout->setContentsMargins(0,0,VALUE_DIS,0);
    //设置部件之间的space
    m_pLayout->setSpacing(0);
    setLayout(m_pLayout);
}

      在这节中,设置按钮图片的函数为SetBtnIcon函数,该函数的原型如下所示:

View Code

void SetBtnIcon(QToolButton *pBtn,eBtnMoustState state,bool bInit=false);

      其中pBtn代表被设置图片的按钮,而eBtnMoustState是一个枚举值,代表该按钮当前的状态,枚举定义如下所示:

View Code

//枚举,按钮状态
enum eBtnMoustState{
     eBtnStateNone,//无效
     eBtnStateDefault,//默认值(如按钮初始显示)
     eBtnStateHover,//鼠标移到按钮上状态
     eBtnStatePress//鼠标按下按钮时状态
 };

      而bInit表示是否是初始化设置,因为在SetBtnIcon函数里需要获得主界面最大化标志值,而这时候主界面窗口构造函数还没完成,同时在SetBtnIcon函数里又需要获得主界面窗口对象,因此会矛盾,所以使用了bInit标志值进行区分。

      SetBtnIcon函数的定义如下代码所示:

View Code

//设置按钮不同状态下的图标
void TitleBar::SetBtnIcon(QToolButton *pBtn,eBtnMoustState state,bool bInit/*=false*/)
{
    //获得图片路径
    QString strImagePath = GetBtnImagePath(pBtn,bInit);
    //创建QPixmap对象
    QPixmap objPixmap(strImagePath);
    //得到图像宽和高
    int nPixWidth = objPixmap.width();
    int nPixHeight = objPixmap.height();
    //如果状态不是无效值
    if(state!=eBtnStateNone)
    {
        /*设置按钮图片
        按钮的图片是连续在一起的,如前1/4部分表示默认状态下的图片部分,接后的1/4部分表示鼠标移到按钮状态下的图片部分
        */
        pBtn->setIcon(objPixmap.copy((nPixWidth/4)*(state-1),0,nPixWidth/4,nPixHeight));
        //设置按钮图片大小
        pBtn->setIconSize(QSize(nPixWidth/4,nPixHeight));
    }
}

View Code

//获得图片路径(固定值)
const QString TitleBar::GetBtnImagePath(QToolButton *pBtn,bool bInit/*=false*/)
{
    QString strImagePath;
    //皮肤按钮
    if(m_pBtnSkin==pBtn)
    {
        strImagePath = ":/image/SkinButtom.png";
    }
    //菜单按钮
    if(m_pBtnMenu==pBtn)
    {
        strImagePath = ":/image/title_bar_menu.png";
    }
    //最小化
    if(m_pBtnMin==pBtn)
    {
        strImagePath = ":/image/sys_button_min.png";
    }
    //最大化/还原按钮,所以包括最大化和还原两张图片
    if(m_pBtnMax==pBtn)
    {
        //如果是初始设置或者主界面的最大化标志不为真(其中MainWindow::Instance()使用单例设计模式)
        if(bInit==true || MainWindow::Instance()->GetMaxWin()==false)
        {
            //最大化按钮图片路径
            strImagePath = ":/image/sys_button_max.png";
        }
        else
        {
            //还原按钮图片路径
            strImagePath = ":/image/sys_button_restore.png";
        }
    }
    //关闭按钮
    if(m_pBtnClose==pBtn)
    {
        strImagePath = ":/image/sys_button_close.png";
    }
    return strImagePath;
}

二、设置按钮其他效果

      各位在使用360安全卫士的时候,把鼠标移到关闭按钮上或者使用鼠标按下关闭按钮,其呈现不同的图片以示区分,当然其他按钮也一样。那么是不是也和工具栏按钮一样,子类化一个按钮了?不需要。使用事件过滤器,在标题栏部件中进行事件判断和目标判断即可。

      首先是创建事件过滤器,代码如下所示:

View Code

//创建事件过滤器
void TitleBar::CreateEventFiter()
{
    m_pBtnSkin->installEventFilter(this);
    m_pBtnMenu->installEventFilter(this);
    m_pBtnMin->installEventFilter(this);
    m_pBtnMax->installEventFilter(this);
    m_pBtnClose->installEventFilter(this);
}

      然后在标题栏部件中重写eventFilter函数即可,代码如下:

View Code

//事件过滤
bool TitleBar::eventFilter(QObject *obj, QEvent *event)
{
    //按钮状态
    eBtnMoustState eState = eBtnStateNone;
    //判断事件类型--QEvent::Enter
    if (event->type() == QEvent::Enter)
    {
        eState = eBtnStateHover;
    }
    //判断事件类型--QEvent::Leave
    if (event->type() == QEvent::Leave)
    {
        eState = eBtnStateDefault;
    }
    //判断事件类型--QEvent::MouseButtonPress
    if (event->type() == QEvent::MouseButtonPress && ((QMouseEvent*)(event))->button()== Qt::LeftButton)
    {
        eState = eBtnStatePress;
    }
    //判断目标
    if(m_pBtnSkin==obj || m_pBtnMenu==obj || m_pBtnMin==obj || m_pBtnMax==obj || m_pBtnClose==obj)
    {
        //如果状态有效
        if(eState != eBtnStateNone)
        {
            //根据状态设置按钮图标
            SetBtnIcon((QToolButton *)obj,eState);
            return false;
        }
    }
    return QWidget::eventFilter(obj,event);
}

      即根据事件类型设置按钮状态;最后在各个按钮的click槽函数中实现相应功能即可,如窗口关闭,最大化等。

View Code

//槽函数--slot_btnclick
void TitleBar::slot_btnclick()
{
    QToolButton *pBtn = (QToolButton*)(sender());
    if(pBtn==m_pBtnMin)
    {
        emit signal_min();
    }
    if(pBtn==m_pBtnMax)
    {
        emit signal_maxrestore();
    }
    if(pBtn==m_pBtnClose)
    {
        emit signal_close();
    }
}

      上述代码实现是发送自定义信号;状态栏部分由于很简单就不描述了。

    360安全卫士
    (35)360安全卫士
    安全卫士可以说是国内装机最多的一款电脑卫士软件了,当年杀软普遍收费的情况下打出免费杀软的旗号成就了其目前国内第一安全软件的地位。相比于国内另一款安全软件金山,安全卫士与金山卫士在默认显示的首页上均提供了电脑体检服务,两者提供的体检项目均非常丰富,用户只需点击首页界面上的立即体检按钮即可立即启动系统体检。电脑体检任务执行完毕自动显示体检报告,从实测情况来看,安全卫士是通过给出一个体检得分来评定系统状...更多>>
    金山卫士2016
    (67)金山卫士2016
    国内的安全软件中,除去不说使用最多的应该就是金山的安全软件了。金山卫士与卫士对应采用了金山领先的云安全技术,不仅能查杀上亿已知木马,还能分钟内发现新木马漏洞检测针对优化,速度比同类软件快倍更有实时保护插件清理修复等功能,全面保护您的系统安全。并且金山卫士还有重装系统的功能,打开金山卫士主界面,点击重装系统重装高手一步步进行重装即可这里给大家提供了最新版的金山卫士官方下载。...更多>>
    360杀毒
    (19)360杀毒
    杀毒软件下载官方下载是国内首家免费杀毒软件,开启了国内杀软免费的热潮,尤其使得现在国产软件大部分免费,寻求新的收入模式,杀毒技术采用红伞和两大知名反病毒引擎,双剑合璧查杀监控更凌厉。并基于安全卫士的广大用户以及宁杀错不放过的风格,在国内免费杀毒软件市场雄踞第一的使用量。...更多>>

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(0)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)