光实现弹幕还不够哦~桌面客户端也要做好看点才比较好用~

接下来就跟随 杰洛君 一起实现一个QMainwindow 程序吧~

拖控件与代码实现之间的比较

QMainWindow程序界面的编写在Qt中主要有三种方式:

  • 1.拖动控件
  • 2.代码实现
  • 3.以上二者混合

拖动控件进行界面编写

双击项目中的 mainwindow.ui 就会打开设计模块,左边看到的Layouts,Button等就是控件,你可以拖动进中间的窗体。

右边有一颗控件树,由此我们可以知道,控件以树状结构进行管理。

以上就是拖控件来进行界面编写啦~

控件都在UI 命名空间中,所以你可以看到我们Mainwindow的实现代码总有这么一句 ui->setupUi(this); 访问控件都是用ui进行访问。

不过呢,杰洛君的这个应用还是非常传统地用代码实现了,没有用到控件,主要是杰洛君比较笨,没有学会用好这个设计软件TAT
(p.s. 为了都试着用代码写,所以mainwidnow.ui中的菜单栏,状态栏我全都右键删除了~)

这两种方法各有优势,没有孰优孰劣之说,总之你喜欢就好~

那么,接下来。。。

具体的就以这个为示例,说下如何做一个这样子的程序。

先来一段分析

上面图中的界面如何实现?

观察可以知道,这个应用有很明显分为三个部分:

  • 标题栏(黑色部分)
  • 图片栏(蓝色部分)
  • 控制台(白色部分)

我们简化它 , 发现它的结构如下图般简单~

那就开始一部分一部分地实现吧~

首先是标题栏~

你可以看到杰洛君并没有采用系统的标题栏,所以你在不同系统中看到的标题栏效果是一致的。

小思考
提问:自定义标题栏的优点和缺点各有那些呢?

回答:
自定义标题栏优点:
1. 可以让界面画风一致,因为有时你的程序风格与系统原生界面是不一致的,自定义标题栏比较好看,防止画风突变(^__^)~
2.不同平台下标题栏风格是一致的~

自定义标题栏缺点:
1.放弃了系统原生的标题栏意味着,放弃了系统原生实现好的那些拖放功能,最大化最小化,拉伸的功能等。也就是说这些功能都是需要自己实现的。

既然放弃了很多系统原生功能,为了简化,那就那把应用的大小设置为固定的吧~这样可以专注学习布局,不用去实现拉伸,大大降低难度~

实现一个自定义标题栏吧

就如上面所说的,先固定窗体大小,剩下的就好办了。

设置窗体固定大小很简单 在mainwindow的构造函数中

this->setFixedSize(900,600);

固定为宽为900,高为600的一个窗体。

然后杰洛君创建一个新的类,TitleWidget 它集成自QWidget,并且重载它的paintEvent 函数。

把这个类作为我们的标题栏~

于是它至少应该是这个样子:

class TitleWidget : public QWidget
{Q_OBJECT
public:explicit TitleWidget(QWidget *parent = 0);signals:public slots:protected:void paintEvent(QPaintEvent *);};

为了让窗体的背景有一个渐变的效果,这里我们重载paintEvent

void TitleWidget::paintEvent(QPaintEvent *){// 设置画笔QPen objPen(Qt::NoBrush,1);QPainter Painter(this);Painter.setPen(objPen);//设置渐变画刷QLinearGradient objLinear(rect().topLeft(),rect().bottomLeft());//顶部颜色和透明度objLinear.setColorAt(0,QColor(50,50,50,240));//中间颜色和透明度objLinear.setColorAt(0.8,QColor(34,34,34,255));//底部颜色和透明度objLinear.setColorAt(1,QColor(7,7,7,255));QBrush objBrush(objLinear);Painter.setBrush(objBrush);//画圆角矩形//Painter.drawRoundedRect(rect(),5,5);Painter.drawRect(rect());
}

QLinearGradient 用于创建一个渐变填充效果,赋值给画刷就可以绘制出渐变效果了~

这个有什么用?确实很多应用追求扁平化会放弃无意义的渐变,不过像酷狗的桌面歌词还是可以看到这种渐变的使用。

于是一个标题栏窗体就绘制好了,接下来如何放入杰洛君的mainwindow程序中呢。

在MainWindow类中加入 头文件 “TitleWidget.h”以及 QVBoxLayout 头文件

杰洛君在MainWindow类中加入一个私有变量 TitleWidget类型的titleWidget。

同时为了方便管理代码,再在MainWindow类中添加一个函数声明

void initUI();

以后杰洛君的界面代码就写在这个函数中,并在构造函数中调用它,这样就不会造成构造函数长长一大串了。

接下来就是在initUI函数中写入耿直的代码了:

    titleWidget = new TitleWidget(this);titleWidget->setFixedHeight(50);titleWidget->setFixedWidth(900);QVBoxLayout * mainLayout = new QVBoxLayout(this);mainLayout->addWidget(titleWidget);

上面的代码中 杰洛君用到了一个布局类 QVBoxLayout 这个是让Widget 垂直排布的一个布局 ,说到V -> vertical。

举一反三,Qt 中有一个QHBoxLayout 布局类 ,说到H 自然是horizon 与水平有关 (杰洛君才,才没有想歪呢,真,真的哦,我还只是个孩子,H什么滴真的不懂呀 (>\\\\<) )

自定义标题栏按钮

一个标题栏,一般左边是程序的Logo 右边有最大化最小化与关闭。这里我们做了简化,只有最小化与关闭按钮。

按钮的话 自然是用Qt 的QPushButton啦~

来来来在MainWindow中添加几个QPushButton类型的私有变量吧~

  • miniBut 最小化按钮
  • closeBut 关闭按钮
  • logoBut Logo按钮

然后实现它们。

miniBut = new QPushButton(this);miniBut->setFixedSize(29,32);//连接最小化事件        QObject::connect(miniBut,SIGNAL(clicked()),this,SLOT(showMinimized()));closeBut = new QPushButton(this);closeBut->setFixedSize(38,32);
//连接关闭槽函数,这个槽函数是自己定义的,里面用动画使窗体渐变退出QObject::connect(closeBut,SIGNAL(clicked()),this,SLOT(closeWidget()));logoBut = new QPushButton(this);logoBut->setFixedSize(376, 46);

上面提到的closeWidget()是一个槽函数。

在Mainwindow类中添加

private slots:
bool closeWidget();

并且实现它:

bool MainWindow::closeWidget()      //关闭按钮关联的槽函数
{//界面动画,改变透明度的方式消失1 - 0渐变QPropertyAnimation *animation = new QPropertyAnimation(this, "windowOpacity");animation->setDuration(1500);animation->setStartValue(1);animation->setEndValue(0);animation->start();connect(animation, SIGNAL(finished()), this, SLOT(close()));return true;
}

于是关闭的时候你会看到个很有趣的效果。

杰洛君看到这些按钮是水平布局的,所以就用QHBoxLayout 进行布局

QHBoxLayout * titleLayout = new QHBoxLayout();
//新建了一个QHBoxLayout水平布局,这个水平布局是用来放Logo按钮  最小化按钮 还有关闭按钮的~titleLayout->addSpacing(5);     //加个间隔,不让logo按钮太贴边titleLayout->addWidget(logoBut);        //加入logo按钮titleLayout->addStretch(0);       //加个弹簧,弹簧默认把控件往两端挤titleLayout->addWidget(miniBut);    //加最小化titleLayout->addWidget(closeBut);   //加关闭按钮titleLayout->setSpacing(0);      //设置水平布局默认间隔为0  默认不为0会有点难看titleLayout->setMargin(2);      //设置控件间隔titleWidget->setLayout(titleLayout);        //把这个水平布局放入titleWidget中

现在你会看到你的标题栏虽然已经初具形态,可惜仍然丑得可以。然我们先忽视丑丑的它,我们来看看如何实现一个标题栏该有的一个功能– – 拖动~

实现窗体拖动

窗体的拖动是很容易实现的,杰洛君是如何理解这个窗体的拖动呢?

  • 重载鼠标按下事件,鼠标单击并没有释放时,设置按下(一个bool类型变量)为真,记录鼠标坐标与窗体初始坐标。
  • 如果鼠标没有释放并进行移动,记录移动位置的坐标。
  • 重载鼠标移动事件,每次都移动窗体位置为当前窗体位置+鼠标移动位置-鼠标按下位置。
  • 重载鼠标释放事件,设置按下为false。

为此我们在MainWindow类中添加了几个私有变量:

  • QPoint startPos; //窗体初始位置
  • QPoint clickPos; //鼠标单击位置
  • bool isLeftPressDown; //判断是否左键按下

重载窗体的事件函数,在Mainwindow中添加:

protected:
//三个鼠标事件 按下 移动 释放void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);

并实现它们:

void MainWindow::mousePressEvent(QMouseEvent *event)        //Qt的鼠标时间函数重载,下面三个函数共同实现了一个功能,那就是点击窗口任意位置可以拖动窗口移动
{if(event->button()&Qt::LeftButton){startPos = this->pos();clickPos = mapToGlobal(event->pos());isLeftPressDown = true;this->setFocus();}
}void MainWindow::mouseMoveEvent(QMouseEvent *event)
{if (this->isMaximized())return;if(isLeftPressDown)this->move(startPos+event->globalPos()-clickPos);event->accept();
}void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{//鼠标释放事件//自身重绘repaint();//如果是左键if(event->button() == Qt::LeftButton) {//左键按下参数为空isLeftPressDown = false;}
}

鼠标事件中的参数有鼠标的坐标 event->pos(); 但是这个坐标是相对于这个事件函数所属窗体的。

全局的鼠标坐标获取需要用 event->globalPos()

为了得到显示器坐标,用mapToGlobal()进行转换。

更加详细的建议按下F1 查看帮助文档进行进一步学习哦~

你会看到你已经可以通过拖动窗体进行移动了,不需要系统原生标题栏了~

快快愉快滴去掉它!

在MainWindow构造函数中添加这样一行代码

setWindowFlags( Qt::FramelessWindowHint|Qt::WindowSystemMenuHint| Qt::WindowMinimizeButtonHint);

好这样就去掉了系统标题栏了~

可惜标题栏还是丑成狗狗呀!

小C:我不要丑丑的界面T_T

杰洛君:没有美工技能滴骚年伤不起(虎摸

不急,接下来我们来美化它~

美化自定义标题栏

真正丑的其实是那三个按钮。

杰洛君看到很多软件用到滴按钮都是三态按钮:

  • 普通状态
  • 鼠标在上面悬停会有高亮(外发光之类的)
  • 鼠标按下会有凹陷(内发光之类的)

比如老版迅雷看看:
– –普通状态
– –悬停状态
– –按下状态

这个怎么做呢?

重载按钮?有点小烦 – – T_T 今晚已经写很多代码了,不想写了啦!

有没有简单点的方法

有!

就用QSS来实现一个简单的三态按钮吧~

QSS是什么?
文档有写到定义,这里就不介绍了
看到这个名字QSS,相信会一点网络编程的同学都会想到CSS。
没错Qt也可以用类似CSS的代码进行美化。

举个例子:

    closeBut->setStyleSheet("QPushButton{border-image: url(:/project/close1);}""QPushButton:hover{border-image: url(:/project/close2);}""QPushButton:pressed{border-image: url(:/project/close3);}");

这么写看上去有点奇怪,但是这几行字符串会合并为一条长字符串,这可是利用C++的特性呀~忘记的同学快去补补C++

如果不了解CSS,可以跟着杰洛君看这几个点:

第一行 类名{图片:url(图片路径)}

第二行 类名:悬停{图片:url(图片路径)}

第三行 类名:按下{图片:url(图片路径)}

就是这样把按钮三个状态对应的不同图片给设置好了。

接下来你需要做的就是 ,找资源图片,把按钮设置得和图片一样大(否则会拉伸很难看)利用QSS 实现三态,美化自己的标题栏~

后续

今天和大家一起实现了一个自定义标题栏,呼,有点小累~

QSS是个利器,大家可以好好看看~

后续会继续窗体的实现~

今天就到这里吧~O(∩_∩)O哈哈~

用Qt实现一个桌面弹幕程序(五)-- -- 桌面客户端实现①相关推荐

  1. 利用QT编写一个简单爬虫程序

    从高中到大学,一直在固定小说网中下载小说,小说网停机过好几次但最后又起死回生.最近萌发一个想法,把小说网里的小说都爬下来.. 既然要爬网站肯定要对网站结构十分了解,幸好小说网没有弄什么登陆防爬措施,结 ...

  2. Windows桌面应用程序(1-2-4-2nd) 桌面窗口管理器

    在Windows Vista之前,Windows程序会直接画到屏幕上.换句话说,程序会直接写入显卡所显示的内存缓冲区.如果窗口没有正确重绘,这种方法会导致视觉失真.例如,如果用户在另一个窗口上拖动了一 ...

  3. Qt安装和QML HelloWord程序

    QT Win7开发环境安装配置 Qt是一个跨平台应用程序和用户界面框架,使用C + +或者QML,类似CSS和JavaScript开发语言. 它提供给应用程序开发者建立艺术级的图形用户界面所需的所用功 ...

  4. 如何在 Python 中构建跨平台桌面应用程序

    如何在 Python 中构建跨平台桌面应用程序 开发桌面 GUI 应用程序曾经是一个乏味.容易出错且缓慢的过程. 当然,Python 在整体上极大地简化了应用程序开发,但在 GUI 领域,仍然没有真正 ...

  5. Qt实现一个简单的应用程序——桌面助手

    一.软件功能及涉及知识 1.实现不同功能之间的界面切换 2.可查看日历 3.可实现计时器功能 4.可实现计算器功能 5.ui界面及按钮部件背景的设置 6.为软件设置图标 7.程序打包成软件 二.效果演 ...

  6. 桌面linux imx6q,SAIL-IMX6Q添加qt桌面应用程序

    添加qt桌面应用程序比较繁琐,提起来大家都是相当头疼的一块项目,经过我一系列的摸索,终于学会了用imx6添加qt桌面应用程序. 文件夹设置存放在:/usr/share/matchbox/vfolder ...

  7. Qt Creator创建一个移动应用程序

    Qt Creator创建一个移动应用程序 创建一个移动应用程序 搭建开发环境 创建项目 创建Accelbubble主视图 移动泡沫 锁定装置方向 添加依赖项 运行应用程序 创建一个移动应用程序 本教程 ...

  8. 使用PHP-GTK编写一个windows桌面应用程序

    PHP-GTK的下载地址:http://gtk.php.net/download.php?language=en-US, 猿哥选择了最新版本(beta版),可能有人会问我们为啥不选最新的stable版 ...

  9. 建立一个vs+qt打开系统摄像头的程序

    在上一篇关于OPENcv的文章中已经讲解了opencv环境配置,这次结合qt做一个实际程序,我是用qt做界面,vs编程写程序,和qtcreat的也很相似.QT的配置点击打开链接可以看这个博主也可以自己 ...

最新文章

  1. linux裸设备文件系统,Linux当中的文件系统
  2. 2017202110104-高级软件工程2017第8次作业—个人总结
  3. hdu 4513(manacher+dp)
  4. 预训练模型真的越大越好吗?听听他们怎么说
  5. windows环境下 curl 安装和使用
  6. 用纯CSS实现3D立方体效果
  7. golang断言的使用(Type Assertion)
  8. 在Linux上安装JDK9
  9. 项目管理的成功方程式
  10. Solr系列二:solr-部署详解(solr两种部署模式介绍、独立服务器模式详解、SolrCloud分布式集群模式详解)...
  11. 加快网站速度的最佳做法_(4)避免使用css表达式
  12. 游戏设计要素探秘之术语的呼唤
  13. 离线版-端点检测代码重写
  14. 《Python 编程从入门到实践》 ———— Python学习笔记完结篇
  15. Unix网络编程-同步
  16. oracle vm virtualbox无网络连接_VirtualBox 安装 Windows 2000/XP 测试
  17. 如何将nideshop部署到本地
  18. CH579 以太网转串口 串口服务器代码!
  19. 使用SSH公钥登录服务器
  20. 这次是100秒 蓝箭航天80吨液氧甲烷发动机100%推力试车

热门文章

  1. Opengl实现纹理贴图
  2. AT2401C与RFX2401C的开发区别
  3. 如何在1微秒内检测数以万计的ip段
  4. 基于嵌入式或单片机的音乐盒制作
  5. Unity 常用插件
  6. c语言新建一个单向链表菜鸟,【图片】菜鸟的进击——玩转C语言链表【c程序设计吧】_百度贴吧...
  7. 手机APP支付--整合支付宝支付控件
  8. spring boot 集成sleuth
  9. Shiro学习笔记(三)源码解析
  10. 计算机专业事业单位类别,计算机管理岗位是属于事业单位考试中的哪类?