这篇博文主要讲解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样式表对其进行样式设置,当然还有其他方法。

//设置子部件样式(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;}");
}

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

//创建设置布局
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函数,该函数的原型如下所示:

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

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

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

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

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

//设置按钮不同状态下的图标
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));}
}

//获得图片路径(固定值)
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安全卫士的时候,把鼠标移到关闭按钮上或者使用鼠标按下关闭按钮,其呈现不同的图片以示区分,当然其他按钮也一样。那么是不是也和工具栏按钮一样,子类化一个按钮了?不需要。使用事件过滤器,在标题栏部件中进行事件判断和目标判断即可。

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

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

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

//事件过滤
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槽函数中实现相应功能即可,如窗口关闭,最大化等。

//槽函数--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();}
}

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

我把二进制文件打包供下载,希望大家提出意见,有什么不对的地方望指教;下载地址为:文件下载

FROM: http://www.cnblogs.com/appsucc/archive/2012/03/28/2421225.html

Qt之实现360安全卫士主界面(四)相关推荐

  1. Qt之实现360安全卫士主界面(转)

    Qt之实现360安全卫士主界面(一) 该博文只是模仿360安全卫士的主界面,并不牵涉其中的任何业务功能:重在个人见解以及界面实现:关于360安全卫士的主界面,我想大家都见到过,毕竟基本大部分人都安装过 ...

  2. Qt之实现360安全卫士主界面

    Qt之实现360安全卫士主界面(一) 该博文只是模仿360安全卫士的主界面,并不牵涉其中的任何业务功能:重在个人见解以及界面实现:关于360安全卫士的主界面,我想大家都见到过,毕竟基本大部分人都安装过 ...

  3. Qt之实现360安全卫士主界面(一)

    转自:http://www.cnblogs.com/appsucc/archive/2012/03/14/2395657.html 该博文只是模仿360安全卫士的主界面,并不牵涉其中的任何业务功能:重 ...

  4. Qt之实现360安全卫士主界面(三)

    这篇博文主要讲述360安全卫士工具栏的创建:工具栏由图片和文字组成,当鼠标移到工具栏按钮上时,需要有些特征表达该现象,如背景色变化等:当然鼠标单击工具栏按钮时,同样也要有些特征,并且这个特征区别于鼠标 ...

  5. qmainwindow 标题栏_Qt之360安全卫士主界面(标题栏)

    其实网上有过360界面一些小细节的实现,基本的也都比较简单,项目完事,闲来无事,就按照自己电脑的360安全卫士9.1做了一个界面,包括托盘.最小化.最大化.界面风格样式美化等! 效果如下: 有人可能会 ...

  6. Qt实现360安全卫士主界面(中央窗体)

    中央窗口可以分为左右两部分,左半边由QWidget实现,包含三个QLabel,一个QPushButton,QLabel主要用来显示图片,文本信息,还有一个按钮负责"立即体验". 右 ...

  7. 【Qt】仿360安全卫士界面(自定义阴影边框类)

    00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 自定义阴影边框类设计与实现 04. 测试代码 05. 示例下载 06. 附录 01. 概述 Qt默认的QDialog和QW ...

  8. 【360安全卫士显示界面异常解决】

    360安全卫士显示界面异常解决 问题/解决 首先打开360安全卫士,单击三横杠 选择设置 选择界面缩放,开启主界面自动缩放功能,点击确定 4.此时360安全卫士界面就显示正常了

  9. Qt实现360安全卫士登录界面

    在分享之前,我们先看截图,用事实说话,有图有真相! 通过点击底部栏的新浪,人人按钮来进行3个界面的互相切换,进行用户删除时,自定义的QDialog用于和用户交互,通过exec()可进入堵塞状态. 界面 ...

最新文章

  1. form表单只提交数据而不进行页面跳转的解决方案
  2. sql 树状结构中知道 父节点与孙节点_集群环境中使用Zookeeper实现分布式幂等控制...
  3. 【调试基础】Part 3 Window操作系统
  4. 1073 Scientific Notation (20 分)【难度: 一般 / 知识点: 字符串 模拟】
  5. 武汉轻工大学计算机学院操作系统复试题目,2016年武汉轻工大学数学与计算机学院计算机组成原理复试考研复试题库...
  6. 2、Flutter 的安装和idea配置
  7. C语言高级编程:如何确定一个变量是有符号还是无符号数
  8. asp 执行 exe_EXE程序加密锁下载-EXE程序加密锁电脑版下载v5.0
  9. Android 城市选择,热门城市,全部城市(美团、滴滴、淘宝)
  10. 微服务系列之ZooKeeper注册中心和Nacos注册中心Nacos和Zookeeper对比
  11. 理解SVN中trunk,branches,tags
  12. 安卓开发仿微信图片拖拽_Android 仿微信朋友圈图片拖拽返回
  13. ERP已经凉凉?低代码平台真能成为下个风口吗?
  14. 万万没想到 Java 中最重要的关键字竟然是这个!
  15. Eclipse 编码常用技巧【不断补充完善】
  16. 暑假前挑战赛1—— A,B题解
  17. STM32开发,使用IAR软件建立工程
  18. 用python做乘法口诀表_如何用python编写乘法口诀表
  19. 求职面试自我介绍技巧
  20. QQ游戏-大家来找茬 外挂

热门文章

  1. 高通WLAN框架学习(1)- -WIFI的认证和log的抓取
  2. MySQL——表的四种关联关系
  3. 做外贸SOHO,真的能实现时间和财富自由吗
  4. 查询应用服务器fc端口wwn号,几种操作系统下如何查看FC HBA卡WWN号
  5. i7 12700k和i7 12700kf哪个好 i712700kf和酷睿i712700k性能差距
  6. 浅谈JavaScript中的Number类型
  7. 2019福建高中计算机会考操作,2019福建省普通高中学业水平考试科目赋分方法
  8. javascript笔记总结篇
  9. PyQt5安装及使用教程
  10. Apache网页优化和安全优化